If optarg (the argument after the flag -s, from Getop library) isn't a digit, I want an error message to be printed and the program terminated, and if it is a digit, size needs to be set to optarg. The problem I have is while a command like the -s r will hit the error message, -s 2 will also, meaning it's interpreting the 2 as a string.
Debugging with for -s 2
#1 printf("%d",atoi(optarg));
#2 printf("%d",isdigit(atoi(optarg)));
I get the int value 2 for line #1, and an int value of 0 for line #2.
So I was wondering why isdigit(atoi(optarg))) gives me a 0, when atoi(optarg) gives me an int. Is there a better way to check if optarg is an int?
int main (int argc, char *argv[]){
int size;
char option;
size = 0;
const char *optstring;
optstring = "rs:pih";
while ((option = getopt(argc, argv, optstring)) != EOF) {
switch (option) {
case 'r':
type_set = 1;
break;
**case 's':
capacity_set = 1;
if(isdigit(atoi(optarg))==0){
fprintf(stderr,"Argument after -s needs to be an int\n");
return 0;
}**
else{
size = atoi(optarg);
}
break;
default{
return 0;
}
isdigit
takes a character and tells you if it is a digit. atoi
takes a string (char *) and returns the number that the string represents. So when you call isdigit(atoi(
... you're taking a number and treating it as a character. Since the charater codes for digits are 48..57, any number other than one of those will return false.
You probably want isdigit(*optarg)
-- this will tell you if the first character of the argument (string) is a digit character. Of course, this only looks at the first character, so you might want isdigit(optarg[0]) && optarg[1] == 0
instead.
If you want to accept a number rather than a digit (and only a number), strtol
works much better than atoi
as it allows you to check for failures. Something like:
char *end;
errno = 0;
size = strtol(optarg, &end, 10);
while (isspace(*end)) ++end;
if (errno || *end) {
// an error occurred on conversion, or there is extra cruft
// after a number in the argument.
fprintf(stderr,"Argument after -s needs to be an int\n");
return 0; }