How do I tell if the c function atoi failed or if

2019-01-06 15:08发布

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.

标签: c++ atoi
6条回答
干净又极端
2楼-- · 2019-01-06 15:35

It's been a while since I've done and C/C++, but it would appear to me that the (overly) simple solution would be to check just the string for "0".

int value = atoi(string_number.c_str());

if ( !value && string_number != "0" ) {
  // error
} else {
  // great success!
}
查看更多
看我几分像从前
3楼-- · 2019-01-06 15:37

Since this is tagged :

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; 
}
查看更多
三岁会撩人
4楼-- · 2019-01-06 15:49

An alternative to strtol is sscanf, although it's a little heavy-weight:

const char *numStr = "12345";  // input string
int value;
if(sscanf(numStr, "%d", &value) == 1)
    ;  // parsing succeeded, use value
else
    ;  // error

However, this allows leading whitespace in your string (which may or may not be desirable), and it allows anything to trail the number, so "123abc" would be accepted and return 123. If you want to have tighter control, go with strtol(), as AndreyT demonstrates.

查看更多
The star\"
5楼-- · 2019-01-06 15:53

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.)

查看更多
做自己的国王
6楼-- · 2019-01-06 15:53

From the man page for strtol():

If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, however, strtol() stores the original value of nptr in *endptr. (Thus, if *nptr is not '\0' but **endptr is '\0' on return, the entire string was valid.)

查看更多
唯我独甜
7楼-- · 2019-01-06 15:56

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.

查看更多
登录 后发表回答