String to integer conversions

There are various functions for converting strings to integers in the C++ standard library. This post is a small overview of these functions. I’ll start with the simplest and go to the more fully featured ones at the end.

The atoi family.

These functions coming from C represent the minimal set of functionality for a string to integer conversion.

int atoi(const char *str);

It only takes a single argument, a c-string and interprets it as a base-10 number. It doesn’t have any error checking built-in either.

  • If the interpreted number doesn’t fit in the return type, it returns some undefined value.
  • If the string can’t be interpreted as number at all (e.g. "Hello") it returns 0.

cppreference link

The strtol family.

These functions again come from C. They already offer some more functionality but might still be lacking on their own.

long strtol(const char *str, char **str_end, int base);

It already takes 3 arguments.

  • The first argument is a c-string again.
  • The 2nd argument is a char **, a pointer to a char pointer that will be set to the address past the last character interpreted as digit. If you pass a nullptr it gets ignored.
  • The 3rd argument is the base used for the conversion. If you pass 0, the base will be decided by the prefix of the string (e.g. octal if prefixed with 0, hexadecimal if prefixed with 0x).

It also includes some error handling.

  • If the value would fall out of range for the return type, it sets errno to ERANGE and returns the min or max value for the return type.
  • If it can’t convert the string (e.g. "Hello") it returns 0.

Now the error handling is a bit bare-bones, especially when it comes to invalid input that can’t be converted so one might rather write a wrapper function around it.

cppreference link

The stoi family.

These functions unlike the other two come from C++ and got introduced with C++11. They are more fully featured and take care of all aspects of error handling.

int stoi(const std::string& str, std::size_t* pos = 0, int base = 10);

There are versions for the different integer return types again, but also overloads for std::string and std::wstring. There are 3 arguments:

  • The first argument is the string you want to convert.
  • The 2nd argument is a std::size_t*, the pointed to size_t will store the index of the first unconverted character. It’s ignored if you pass nullptr.
  • The 3rd argument is the base used for conversion, with 0 for detection based on string prefix.

Since it is from C++ and not taken over from C like the previous functions, it makes use of exceptions for error reporting.

  • It throws std::out_of_range if the converted value would be out of range for the return type.
  • It throws std::invalid_argument if the string can’t be converted at all (our "Hello" string again).

You can see that this family of functions are the only ones really handling the case of an invalid input string that can’t be converted at all being passed in without silently giving a garbage value. And therefore clearly my favorite.

cppreference link

Conclusion

There are 3 different families of functions for these conversions all with different levels of functionality. I’d suggest the C++11 stoi family since it offers highest level of error handling but that’s only my opinion and the others could be (maybe with some wrappers) used too. I also want to point out a Stack Overflow question that got me to write this post:

Binary String to Integer with ‘atoi()’