开发者

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 to ERANGE. ...

Errors

EINVAL...The given base contains an unsupported value. ...

The implementation may also set errno to EINVAL 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜