How do I tell if the c function atoi failed or if it was a string of zeros?

When using the function atoi (or strtol or similar functions for that matter), how can you tell if the integer conversion failed or if the C-string that was being converted was a 0?

For what I'm doing, 0 is an acceptable value and the C-string being converted may contain any number of 0s. It may also have leading whitespace.


The proper function (as long as you are insisting on using C-style functions) is strtol and the conversion code might look as follows

const char *number = "10"; /* for example */

char *end;
long value = strtol(number, &end, 10); 
if (end == number || *end != '\0' || errno == ERANGE)
  /* ERROR, abort */;

/* Success */
/* Add whatever range checks you want to have on the value of `value` */

Some remarks:

strtol allows (meaning: quietly skips) whitespace in front of the actual number. If you what to treat such leading whitespace as an error, you have to check for it yourself.

The check for *end != '\0' makes sure that there's nothing after the digits. If you want to permit other characters after the actual number (whitespace?), this check has to be modified accordingly.

P.S. I added the end == number check later to catch empty input sequences. "All whitespace" and "no number at all" inputs would have been caught by *end != '\0' check alone. It might make sense to catch empty input in advance though. In that case end == number check will/might become unnecessary.


Since this is tagged c++:

template< typename T >
inline T convert(const std::string& str)
{
    std::istringstream iss(str);
    T obj;

    iss >> std::ws >> obj >> std::ws;

    if(!iss.eof())
        throw "dammit!";

    return obj; 
}

For C++11 and later:

The go-to function for string-to-integer conversion is now stoi, which takes a string and returns an int, or throws an exception on error.

No need for the verbose istringstream hack mentioned in the accepted answer anymore.

(There's also stol/stoll/stof/stod/stold for long/long long/float/double/long double conversions, respectively.)