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

后端 未结 6 1433
悲&欢浪女
悲&欢浪女 2020-11-28 09:52

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

相关标签:
6条回答
  • 2020-11-28 10:10

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

    0 讨论(0)
  • 2020-11-28 10:11

    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; 
    }
    
    0 讨论(0)
  • 2020-11-28 10:16

    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.

    0 讨论(0)
  • 2020-11-28 10:19

    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!
    }
    
    0 讨论(0)
  • 2020-11-28 10:28

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

    0 讨论(0)
  • 2020-11-28 10:32

    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.

    0 讨论(0)
提交回复
热议问题