validate input cmdline input argv[] contains all integers
So I have an assignment dealing with number manipulation that also includes error checking. I'm having issues with the error checking side. A user uses the application by via commandline and giving 8 numbers that are space separated. I am having a problem validating that the data provide开发者_如何学God are actually integers.
I was suggested to use the method strtol() however I know that if the integer is invalid, it returns a 0, but I need to return an error message instead of a 0 because 0 is valid. Is there another method I can use to validate input?
strtol
do not have only its return value to signal an error in the conversion, it has also its second parameter (endptr
in my manpage); if you pass to it a pointer to a char *
, it will store there the position of the first character that it couldn't convert, or will leave it alone if nothing could be converted. Thus, you have the following cases:
char * endptr=NULL;
int out=strtol(yourstring, &endptr, 10);
if(endptr==NULL)
{
/* the whole string is garbage - no numbers extracted */
}
else if(*endptr==0)
{
/* the whole string was a number - yay! */
}
else
{
/* strtol extracted a number from the string, but stopped at some invalid character
that you can check by looking at the value of endptr */
}
Moreover, you can also check the value to which strtol
sets errno
in case of problems; EINVAL
is used if nothing could be extracted, the other values can be seen on the manpage of strtol
.
You can also use sscanf
and check its return value to quickly see if the string could or could not be converted to int
(or to whatever you set in the format string).
If strtol()
encounters an error, it will set errno
to EINVAL
. From the man page:
Return Value
The
strtol()
function returns the result of the conversion, unless the value would underflow or overflow. ...In both cases,errno
is set toERANGE
. ...Errors
EINVAL
...The given base contains an unsupported value. ...The implementation may also set
errno
toEINVAL
in case no conversion was performed (no digits seen, and 0 returned).
The command line arguments are strings, why not use isdigit(3)
?
To use strtol
properly, you have to reset errno
before calling it. And if you write code that you want to reuse in other projects, that code should have no unintended side-effects. So there are two variants: a simple one that is probably good enough in your case, and a complex one that would be acceptable in a library of reusable code.
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
/* the simple variant, with the side-effect of changing errno */
static bool is_long_1(const char *s)
{
char *end;
errno = 0;
strtol(s, &end, 10);
return errno == 0 && *end == '\0';
}
/* the complex variant, without side-effects */
static bool is_long_2(const char *s)
{
char *end;
int saved_errno = errno;
errno = 0;
strtol(s, &end, 10);
bool succeeded = errno == 0 && *end == '\0';
errno = saved_errno;
return succeeded;
}
Using one of these functions for checking your arguments should be quite easy, so I leave that part to you to find out.
精彩评论