Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

atoi

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.

like image 322
Jared Avatar asked Oct 28 '09 23:10

Jared


People also ask

What happens if atoi fails in C?

Return Value The atoi() function returns an int value that is produced by interpreting the input characters as a number. The return value is 0 if the function cannot convert the input to a value of that type. The return value is undefined in the case of an overflow.

What does atoi return on failure?

atoi returns the integer value represented by the character string up to the first unrecognized character. If no initial segment of the string is a valid integer, the return value is 0. No indication of overflow or other error is returned, so you should validate the string before calling atoi .

How do I know if strtol failed?

Since strtol() can legitimately return 0, LONG_MAX, or LONG_MIN (LLONG_MAX or LLONG_MIN for strtoll()) on both success and failure, the calling program should set errno to 0 before the call, and then determine if an error occurred by checking whether errno has a nonzero value after the call. According to POSIX.

What does atoi return in C?

Returns. The atoi function returns the integer representation of a string. The atoi function skips all white-space characters at the beginning of the string, converts the subsequent characters as part of the number, and then stops when it encounters the first character that isn't a number.


2 Answers

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.

like image 56
AnT Avatar answered Sep 19 '22 06:09

AnT


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;  } 
like image 30
sbi Avatar answered Sep 23 '22 06:09

sbi