`
#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.
CodePudding user response:
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
0when the conversion failed. However, when this happens, you will not know whether the user actually entered0or 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;
}
