Reputation: 67
`
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// function prototypes
int get_key(int argc, char *argk[]);
int main(int argc, char *argv[]){
char *argv1 = argv[1];
get_key(argc, argv1);
return 0;
}
// function defination.
int get_key(int argc, char *argk){
// ensure single cmd line arg
if(argc < 2 || argc > 2){
printf("usage: ./caesar key(int) !\n");
return 1;
}
char str1[] = "2";
char str2[] = "23";
char str3[] = "a23";
char str4[] = "23b";
char str5[] = "a23b";
int len = strlen(str3);
int number;
for(int i = 0; i < len; i++){
if(isdigit(str3[i])){ // since isdigit() accept only char, not char*.
number = atoi(str3); // meaning if str3 did contain digits 0-9 from ascii chart.
}
}
return number;
}
`
hello guys, please i want to convert argv[1] to integer, without trusting the user. since isdigit() accept only char, not char*, thats why i am iterating through the str3 and atoi accepts char*. it works fine with str1 and str2. but for other string variables, it returns digits within them, for which cant be converted using atoi() or any other calculations. i want to report error messsage if any of argv[1] elements contains non digits 0-9 from ascii chart. thanks.
Upvotes: 1
Views: 408
Reputation: 25396
Since you are stating that the user input cannot be trusted, I don't recommend using the function atoi
, for two reasons:
The behavior is undefined if the converted number is not representable as an int
(i.e. if the number is out of range).
The function will return 0
when the conversion failed. However, when this happens, you will not know whether the user actually entered 0
or whether you got this value due to conversion failure.
Both of these problems can be solved if you use the functon strtol
instead of atoi
.
In your question, you state that you want to reject the input if it contains any non-digit characters. One problem with the function strtol
is that it will skip any leading whitespace characters (e.g. space and tab characters) before attempting to convert a number. If you instead want to reject the input if it contains any leading whitespace characters, then you will have to compare each character with isdigit
, before using the function strtol
. Doing this will also solve the problem of invalid characters after the number, so that input such as 123abc
will get rejected.
Here is a program which will attempt to convert argv[1]
to an integer, while performing full input validation:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
int main( int argc, char *argv[] )
{
long num;
char *p;
//verify that argv[1] is valid
if ( argc < 2 )
{
printf( "not enough parameters!\n" );
exit( EXIT_FAILURE );
}
//verify that argv[1] consists only of digits
for ( p = argv[1]; *p != '\0'; p++ )
{
if ( !isdigit( (unsigned char)*p ) )
{
printf( "first program argument must consist only of digits!\n" );
exit( EXIT_FAILURE );
}
}
//attempt to convert argv[1] to integer
errno = 0;
num = strtol( argv[1], &p, 10 );
//verify that conversion was successful
if ( p == argv[1] )
{
printf( "unable to convert to integer\n" );
exit( EXIT_FAILURE );
}
//verify that no range error occurred
if ( errno == ERANGE )
{
printf( "input is out of range\n" );
exit( EXIT_FAILURE );
}
//everything is ok, so print the result
printf( "The result is: %ld\n", num );
return 0;
}
Upvotes: 1