-1

Say I have an invalid integer input to a char * where,

char *ch = "23 45"

using atoi(ch) gives 23 as the converted output, ignoring the space and 45.

I'm trying to do testing on this input. What can I do to flag it as an invalid input?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
ekeith
  • 644
  • 1
  • 10
  • 33
  • 2
    I recommend using [`strtol`](http://en.cppreference.com/w/c/string/byte/strtol) instead, as it allows validation. – Some programmer dude May 30 '17 at 16:03
  • 1
    https://stackoverflow.com/q/13199693/971127 – BLUEPIXY May 30 '17 at 16:03
  • scanf() and its friends are evil. I'm using fgets(...) in this case @BLUEPIXY – ekeith May 30 '17 at 16:05
  • By the way, what are you actually *expecting*? That the `atoi` function should convert *both* numbers in a single call? That it would skip the space and return the number `2345`? Something else? What is it that actually makes the input invalid? – Some programmer dude May 30 '17 at 16:05
  • 1
    Just like Integer.parseInt in java on a string like this, I want `atoi` to flag this as an invalid string because of the space @Someprogrammerdude – ekeith May 30 '17 at 16:07
  • @ekeith i don't understand you. – BLUEPIXY May 30 '17 at 16:07
  • 3
    Then [`strtol`](http://en.cppreference.com/w/c/string/byte/strtol) it is. Or `scanf` (or `sscanf`) which can *also* be used to validate the input. No, it's not really evil, but it can be misused (like everything else). – Some programmer dude May 30 '17 at 16:09
  • 1
    scanf it is almost always used wrong.... – Michi May 30 '17 at 16:11

2 Answers2

3

Either check the string before passing it to atoi() or use strtol(), though the latter will return long int.

With strtol(), you can check for errors:

RETURN VALUE
       The strtol() function returns the result of the conversion, unless the value would underflow or overflow.  If an underflow occurs, strtol() returns LONG_MIN.  If an overflow
       occurs,  strtol()  returns  LONG_MAX.   In  both cases, errno is set to ERANGE.  Precisely the same holds for strtoll() (with LLONG_MIN and LLONG_MAX instead of LONG_MIN and
       LONG_MAX).

ERRORS
       EINVAL (not in C99) The given base contains an unsupported value.

       ERANGE The resulting value was out of range.

       The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).
syntagma
  • 23,346
  • 16
  • 78
  • 134
2

The lack of error detection is one of the main shortcomings of the atoi() function. If that's something you need, then the basic answer is "don't use atoi()."

The strtol() function is a better alternative in pretty much every way. For your particular purpose, you can pass to it a pointer to a char *, wherein it will record a pointer to the first character in the input that was not converted. If the whole string is successfully converted then a pointer to the string terminator will be stored, so you might write

_Bool is_valid_int(const char *to_test) {
    // assumes to_test is not NULL
    char *end;
    long int result = strtol(to_test, &end, 10);
    return (*to_test != '\0' && *end == '\0');
}
John Bollinger
  • 160,171
  • 8
  • 81
  • 157