Reputation: 456
I'm trying to error check command line arguments to make sure they are integers, and surprisingly having a difficult time doing so. Here is a snippet of code I have that works when all the command line arguments are integers.
Program can have infinite values passed into it.
One example: ./program -p 45 67 3 9 1
for (argCounter = 2; argCounter < argc; argCounter++)
{
total = total * atoi(argv[argCounter]);
}
What happens when a user types 5g
? atoi()
converts it to 5. I need to it to return an error. For some reason I was having trouble getting isdigit()
to work properly as well. I tried so many random things that my head is spinning at this point. So what I'm trying to do is:
for (argCounter = 2; argCounter < argc; argCounter++)
{
//pseudocode
if (argv[argCounter] != integer)
{
printf("Error!");
return 0;
}
total = total * atoi(argv[argCounter]);
}
Upvotes: 0
Views: 313
Reputation: 596256
You can use sscanf()
. Its %n
placeholder can be used to determine the number of characters consumed, which you can compare to the string length:
for (argCounter = 2; argCounter < argc; argCounter++)
{
int value, consumed;
if ((sscanf(argv[argCounter], "%d%n", &value, &consumed) != 1) ||
(argv[argCounter][consumed] != '\0'))
{
printf("Error!");
return 0;
}
total *= value;
}
Or, you can use strtol()
. It can output a pointer to the first unparsed character. You can check to see if that character is a null terminator or not:
for (argCounter = 2; argCounter < argc; argCounter++)
{
char *end;
errno = 0;
long value = strtol(argv[argCounter], &end, 10);
if ((end == argv[argCounter]) ||
(*end != '\0') ||
(((value == LONG_MIN) || (value == LONG_MAX)) && (errno == ERANGE)))
{
printf("Error!");
return 0;
}
total *= value;
}
Upvotes: 4
Reputation: 133
Well I'm quite a beginner and I don't exactly understand what you want to do exactly? if I understand, you want to check if all arguments are numbers (only digits) included in the integer range you want that total contain the produce of the multiplication of all these integers (and I assume you also want total to be in integer range?)
long long total = 1;
for (argCounter = 1; argCounter < argc; argCounter++)
{
char *check_end;
long long nbr = stroll(arg[argCounter], &check_end, 10);
if (!argv[argCounter][0]|| *check_end || nbr > INT_MAX || nbr < INT_MIN || nbr * total > INT_MAX || nbr * total < INT_MIN)
{
total = 0;
printf("Error\n");
break;
}
total *= nbr;
}
maybe this should help, stroll convert a string (given as first parameter) in a base(given as third parameter) to a long long
and set the string's pointer (given as second parameter) to the place on the string where the conversion stopped (\0
if only digits after the sign) you could check the stroll man; anyway im not sure my code is very optimised or functional and you may want to get an int at the end so cast as int total variable to an int variable.
Upvotes: 0