The standard way of converting between numbers and strings in C++11

In C++03 there was no standard way of converting numbers to strings. The best way to do that was using a std::stringstream:

One could put that into a more generic function that looks like this:

The opposite of converting a text to a number could look like this:

Of course, there was also the option of using C functions such as itoa, sprintf or atoi (or their Microsoft secure version _itoa_s, sprintf_s).

C++11 provides several standard functions for converting numbers to strings and strings to numbers, all of them available in the <string> header.

For converting numbers to strings there are two new overloaded functions: to_string() and to_wstring(). They take one argument of various numeric types (int, long, long long, double, long double, etc.) and return either a std::string or a std::wstring with the number converted to text.

These functions are actually just wrappers over sprintf and swprintf. According to the standard (section 21.5):

Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of “%d”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%f”, “%f”, or “%Lf”, respectively, where buf designates an internal character buffer of sufficient size.

For the other way around of converting strings to numbers there are several overloaded methods (taking either a std::string or a std::wstring):

  • stoi: converts a string to a signed integer
  • stol: converts a string to a signed long
  • stoll: converts a string to a signed long long
  • stoul: converts a string to an unsigned long
  • stoull: converts a string to an unsigned long long
  • stof: converts a string to a float
  • stod: converts a string to a double
  • stold: converts a string to a long double

Functions stof, stod and stold are also just wrappers over strtod and strtold:

the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

atoi() and atol() that convert a null-terminated byte-string (i.e. char*) to an integer or long were already available in header <cstdlib>. There is a new function available in this header called atoll() that converts a null-terminated byte string to a long long value.

7 thoughts on “The standard way of converting between numbers and strings in C++11

  1. Balakrishnan B

    Its worth to mention that sto* functions throw exceptions if the input is invalid but in ato* functions, the behaviour is undefined for invalid inputs.

    Reply
  2. Michael Nicolella (@MikeNicolella)

    How strict is the standard for the implementation of std::to_string and std::stod – is it required to perfectly round-trip all doubles, so that double -> string -> double results in exactly the same binary as the original double?

    Reply
    1. Marius Bancila Post author

      The standard says (21.5) for to_string:

      Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of “%d”, “%u”, “%ld”, “%lu”, “%lld”, “%llu”, “%f”, “%f”, or “%Lf”, respectively, where buf designates an internal character buffer of sufficient size.

      and for stof, stod and stold:

      the first two functions call strtod(str.c_str(), ptr) and the third function calls strtold(str.c_str(), ptr). Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.

      Reply
      1. robdesbois

        It would be worth showing the full signature of the stofoo() functions, since without seeing e.g. int stoi(const string& str, size_t *idx = 0, int base = 10); the mention of idx in the standard extract doesn’t make sense.

        Reply
  3. Felix

    Maybe it’s also worth mentioning that std::stoi and friends throw exceptions in case of invalid arguments (std::invalid_arguments) or under/overflows (std::out_of_range), as opposed to the C++98 std::atoi, which simply returns 0 in case of problems.

    Reply
  4. Bla

    Coming back to the round-tripping of doubles: can the precision used for std::to_string(double) be set somewhere? otherwise you end up with the standard precision which is not suitable for round-tripping…

    Reply

Leave a Reply