How it works...

To convert between an integral or floating point type to a string type, you can use either the std::to_string() or std::to_wstring() function. These functions are available in the <string> header and have overloads for signed and unsigned integer and real types. They produce the same result as std::sprintf() and std::swprintf() would produce when called with the appropriate format specifier for each type. The following code snippet list all the overloads of these two functions.

    std::string to_string(int value); 
std::string to_string(long value);
std::string to_string(long long value);
std::string to_string(unsigned value);
std::string to_string(unsigned long value);
std::string to_string(unsigned long long value);
std::string to_string(float value);
std::string to_string(double value);
std::string to_string(long double value);
std::wstring to_wstring(int value);
std::wstring to_wstring(long value);
std::wstring to_wstring(long long value);
std::wstring to_wstring(unsigned value);
std::wstring to_wstring(unsigned long value);
std::wstring to_wstring(unsigned long long value);
std::wstring to_wstring(float value);
std::wstring to_wstring(double value);
std::wstring to_wstring(long double value);

When it comes to the opposite conversion, there is an entire set of functions that have the name with the format ston (string to number), where n stands for i (integer), l (long), ll (long long), ul (unsigned long), or ull (unsigned long long). The following listing shows all these functions, each of them with two overloads, one that takes an std::string and one that takes an std::wstring as the first parameter:

    int stoi(const std::string& str, std::size_t* pos = 0,  
int base = 10);
int stoi(const std::wstring& str, std::size_t* pos = 0,
int base = 10);
long stol(const std::string& str, std::size_t* pos = 0,
int base = 10);
long stol(const std::wstring& str, std::size_t* pos = 0,
int base = 10);
long long stoll(const std::string& str, std::size_t* pos = 0,
int base = 10);
long long stoll(const std::wstring& str, std::size_t* pos = 0,
int base = 10);
unsigned long stoul(const std::string& str, std::size_t* pos = 0,
int base = 10);
unsigned long stoul(const std::wstring& str, std::size_t* pos = 0,
int base = 10);
unsigned long long stoull(const std::string& str,
std::size_t* pos = 0, int base = 10);
unsigned long long stoull(const std::wstring& str,
std::size_t* pos = 0, int base = 10);
float stof(const std::string& str, std::size_t* pos = 0);
float stof(const std::wstring& str, std::size_t* pos = 0);
double stod(const std::string& str, std::size_t* pos = 0);
double stod(const std::wstring& str, std::size_t* pos = 0);
long double stold(const std::string& str, std::size_t* pos = 0);
long double stold(const std::wstring& str, std::size_t* pos = 0);

The way the string to integral type functions work is by discarding all white spaces before a non-whitespace character, then taking as many characters as possible to form a signed or unsigned number (depending on the case), and then converting that to the requested integral type (stoi() will return an integer, stoul() will return an unsigned long, and so on). In all the following examples, the result is integer 42, except for the last example where the result is -42:

    auto i1 = std::stoi("42");             // i1 = 42 
auto i2 = std::stoi(" 42"); // i2 = 42
auto i3 = std::stoi(" 42fortytwo"); // i3 = 42
auto i4 = std::stoi("+42"); // i4 = 42
auto i5 = std::stoi("-42"); // i5 = -42

A valid integral number may consist of the following parts:

  • A sign, plus (+) or minus (-) (optional).
  • Prefix 0 to indicate an octal base (optional).
  • Prefix 0x or 0X to indicate a hexadecimal base (optional).
  • A sequence of digits.

The optional prefix 0 (for octal) is applied only when the specified base is 8 or 0. Similarly, the optional prefix 0x or 0X (for hexadecimal) is applied only when the specified base is 16 or 0.

The functions that convert a string to an integer have three parameters:

  • The input string.
  • A pointer that when not null will receive the number of characters that were processed and that can include any leading white spaces that were discarded, the sign, and the base prefix, so it should not be confused with the number of digits the integral value has.
  • A number indicating the base; by default, this is 10.

The valid digits in the input string depend on the base. For base 2, the only valid digits are 0 and 1; for base 5, they are 01234. For base 11, the valid digits are 0-9 and characters A and a. This continues until we reach base 36 that has valid characters 0-9, A-Z, and a-z.

The following are more examples of strings with numbers in various bases converted to decimal integers. Again, in all cases, the result is either 42 or -42:

    auto i6 = std::stoi("052", nullptr, 8); 
auto i7 = std::stoi("052", nullptr, 0);
auto i8 = std::stoi("0x2A", nullptr, 16);
auto i9 = std::stoi("0x2A", nullptr, 0);
auto i10 = std::stoi("101010", nullptr, 2);
auto i11 = std::stoi("22", nullptr, 20);
auto i12 = std::stoi("-22", nullptr, 20);

auto pos = size_t{ 0 };
auto i13 = std::stoi("42", &pos); // pos = 2
auto i14 = std::stoi("-42", &pos); // pos = 3
auto i15 = std::stoi(" +42dec", &pos);// pos = 5

An important thing to note is that these conversion functions throw if the conversion fails. There are two exceptions that can be thrown:

  • std::invalid_argument: If the conversion cannot be performed:
        try 
{
auto i16 = std::stoi("");
}
catch (std::exception const & e)
{
// prints "invalid stoi argument"
std::cout << e.what() << std::endl;
}
  • std::out_of_range: If the converted value is outside the range of the result type (or if the underlying function sets errno to ERANGE):
        try 
{
// OK
auto i17 = std::stoll("12345678901234");
// throws std::out_of_range
auto i18 = std::stoi("12345678901234");
}
catch (std::exception const & e)
{
// prints "stoi argument out of range"
std::cout << e.what() << std::endl;
}

The other set of functions that convert a string to a floating point type is very similar, except that they don't have a parameter for the numeric base. A valid floating point value can have different representations in the input string:

  • Decimal floating point expression (optional sign, sequence of decimal digits with optional point, optional e or E followed by exponent with optional sign).
  • Binary floating point expression (optional sign, 0x or 0X prefix, sequence of hexadecimal digits with optional point, optional p or P followed by exponent with optional sign).
  • Infinity expression (optional sign followed by case insensitive INF or INFINITY).
  • A non-number expression (optional sign followed by case insensitive NAN and possibly other alphanumeric characters).

The following are various examples of converting strings to doubles:

    auto d1 = std::stod("123.45");         // d1 =  123.45000000000000 
auto d2 = std::stod("+123.45"); // d2 = 123.45000000000000
auto d3 = std::stod("-123.45"); // d3 = -123.45000000000000
auto d4 = std::stod(" 123.45"); // d4 = 123.45000000000000
auto d5 = std::stod(" -123.45abc"); // d5 = -123.45000000000000
auto d6 = std::stod("1.2345e+2"); // d6 = 123.45000000000000
auto d7 = std::stod("0xF.6E6666p3"); // d7 = 123.44999980926514

auto d8 = std::stod("INF"); // d8 = inf
auto d9 = std::stod("-infinity"); // d9 = -inf
auto d10 = std::stod("NAN"); // d10 = nan
auto d11 = std::stod("-nanabc"); // d11 = -nan

The floating-point base 2 scientific notation, seen earlier in the form 0xF.6E6666p3, is not the topic of this recipe. However, for a clear understanding, a short description is provided; although, it is recommended that you see additional references for details. A floating-point constant in the base 2 scientific notation is composed of several parts:

  • The hexadecimal prefix 0x.
  • An integer part, in this example was F, which in decimal is 15.
  • A fractional part, which in this example was 6E6666, or 011011100110011001100110 in binary. To convert that to decimal, we need to add inverse powers of two: 1/4 + 1/8 + 1/32 + 1/64 + 1/128 + ....
  • A suffix, representing a power of 2; in this example, p3 means 2 at the power of 3.

The value of the decimal equivalent is determined by multiplying the significant (composed of the integer and fractional parts) and the base at the power of exponent. For the given hexadecimal base 2 floating point literal, the significant is 15.4312499... (note that digits after the seventh one are not shown), the base is 2, and the exponent is 3. Therefore, the result is 15.4212499... * 8, which is 123.44999980926514.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset