I have a program that needs to get an int from the user from the command line
int main(int argc, char* argv[])
My only problem is that I need to check whether argv is an int. If it isn't, I need to return an error. How can I do that? I have to check if the input is an int before using atoi. Can someone help me?
Here's one way, using strtol and checking the end of the string:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc,char **argv)
{
char *cp;
long lval;
int val;
// skip over program name
--argc;
++argv;
if (argc < 1) {
fprintf(stderr,"main: no argument specified\n");
exit(1);
}
cp = *argv;
if (*cp == 0) {
fprintf(stderr,"main: argument an empty string\n");
exit(1);
}
lval = strtol(cp,&cp,10);
if (*cp != 0) {
fprintf(stderr,"main: argument '%s' is not an integer -- '%s'\n",
*argv,cp);
exit(1);
}
val = (int) lval;
// NOTE: just going for extra credit here ;-)
// ensure number fits in a int (since strtol returns long and that's 64
// bits on a 64 bit machine)
#if 1
if (val != lval) {
fprintf(stderr,"main: argument '%s' (with value %ld) is too large to fit into an integer -- truncated to %d\n",
*argv,lval,val);
exit(1);
}
#endif
printf("val=%d\n",val);
return 0;
}
UPDATE:
Minor: Code does not detect conversion overflow of strtol() Code incorrectly assumes range of long more than int. If same range,
if (val != lval)is always true. Suggest looking aterrno, INT_MAX,INT_MIN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
int
main(int argc,char **argv)
{
char *cp;
long lval;
int val;
// skip over program name
--argc;
++argv;
if (argc < 1) {
fprintf(stderr,"main: no argument specified\n");
exit(1);
}
cp = *argv;
if (*cp == 0) {
fprintf(stderr,"main: argument an empty string\n");
exit(1);
}
errno = 0;
lval = strtol(cp,&cp,10);
if (*cp != 0) {
fprintf(stderr,"main: argument '%s' is not an integer -- '%s'\n",
*argv,cp);
exit(1);
}
// on a 32 bit machine, entering 2147483648 will produce a non-zero errno
if (errno) {
fprintf(stderr,"main: argument '%s' parse error -- '%s'\n",
*argv,strerror(errno));
exit(1);
}
// on a 64 bit machine, entering 2147483648 will not produce an error, so
// we should check the range ourselves
if ((lval < INT_MIN) || (lval > INT_MAX)) {
fprintf(stderr,"main: argument '%s' range error -- %ld outside of range (%ld to %ld)\n",
*argv,lval,(long) INT_MIN,(long) INT_MAX);
exit(1);
}
val = (int) lval;
// NOTE: just going for extra credit here ;-)
// ensure number fits in a int (since strtol returns long and that's 64
// bits on a 64 bit machine)
// FIXME -- with above tests this can never be true (i.e. fault), so
// I've nop'ed it -- left in to show prior/original test
#if 0
if (val != lval) {
fprintf(stderr,"main: argument '%s' (with value %ld) is too large to fit into an integer -- truncated to %d\n",
*argv,lval,val);
exit(1);
}
#endif
printf("val=%d\n",val);
return 0;
}
Command line argument validation in C
I need to check whether argv is an int
argv[] contains a string by checking argc. for (int a = 1; a < argc; a++) {
int_validation(argv[a]);
}
strtol()
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
void int_validation(const char *s) {
// If leading space not OK
// isspace() only valid in unsigned char range and EOF.
if (isspace(*(unsigned char *)s)) {
puts("Fail - leading spaces");
return;
}
// Convert
int base = 0; // Use 10 for base 10 only input
char *endptr;
errno = 0;
long val = strtol(s, &endptr, base);
if (s == endptr) { // When endptr is same as s, no conversion happened.
puts("Fail - no conversion");
return;
}
// detect overflow
if (errno == ERANGE || val < INT_MIN || val > INT_MAX) {
errno = ERANGE;
puts("Fail - overflow");
return;
}
// If trailing space OK, seek pass them
while (isspace(*(unsigned char *)endptr)) {
endptr++;
}
// If trailing non-numeric text bad
if (*endptr) {
puts("Fail - overflow");
return;
}
printf("Success %d\n", (int) val);
return;
}
Adjust return type and messages as desired.
Typically input like "1e5" or "123.0", although mathematically a whole number, is not consider valid int input. Additional code needed to allow those.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With