c++wstring

to_wstring().size() isn't behaving as expected


I have a double variable, the contents of which need to be converted into a string. I need to calculate, how long that string would end up being, so I tried using size(), but that leads to unexpected results.

From this:

double test_double;
test_double = 12.34;
std::wstring test_string = L"12.34";
std::wcout << L"string is: " << test_string << std::endl;
std::wcout << L"length of string is: " << test_string.size() << std::endl; //this shows expected result
std::wcout << L"double is: " << test_double << std::endl;
std::wcout << L"length of double is: " << (std::to_wstring(test_double)).size() << std::endl; //and this makes me wonder

I get this output:

string is: 12.34
length of string is: 5
double is: 12.34
length of double is: 9

The strings seem to end up being identical, but the result of a conversion is different for some reason. Am I missing something?


Solution

  • The documentation for std::to_wstring (https://en.cppreference.com/w/cpp/string/basic_string/to_wstring) states that it "Converts a floating point value to a wide string as if by std::swprintf(buf, sz, L"%f", value)".

    If we look at the documentation for swprintf (https://en.cppreference.com/w/cpp/io/c/fwprintf) and look at the f format specifier, we see that it defaults to 6 digits of precision. This is leading to the string 12.340000.

    std::cout is going to (by default) format doubles according to the defaultfloat IO manipulator described here: https://en.cppreference.com/w/cpp/io/manip/fixed. Importantly, you can see in their example that it will truncate zeroes and will thus produce 12.34 in this case.

    When you explicitly convert to a string with std::to_wstring, you are now providing an explicit string to std::cout and so it doesn't try to be clever and truncate for you. When you give a double to std::cout, it has to make a decision as to what is the appropriate way to display the number (fixed digits, scientific, etc.). It turns out that the default behavior is simply not what you want in this case it seems.