std::cout.imbue() does not work, but std::locale::global() works
-
Please help me to understand behaviour of this simple program (My config: Windows 7, VS2013, codepage Windows-1251 for string literals encoding, the same is default system-wide, CP 866 codepage for console):
**std::cout << 1.2 << " Hi! Привет!" << std::endl; //Prints 1.2 Hi! ╧ЁштхЄ!
std::locale locale("");
std::cout.imbue(locale);
std::cout << 1.2 << " Hi! Привет!" << std::endl; //Prints 1,2 Hi! ╧ЁштхЄ!std::locale::global(locale);
std::cout << 1.2 << " Hi! Привет!" << std::endl; //Prints 1,2 Hi! Привет!**The «╧ЁштхЄ» is how «Привет!» looks like when wrongly interpreted as CP 866 instead of 1251.
For unknown reasons
std::cout.imbue(locale)
changes only decimal separator, but not output encoding, so I get wrong results.std::locale::global(locale)
does good job, but I cannot use it, because it changes behaviour of std::stof (std::stof("1.2")
will return 1, which I do not want).It is also unfair that «Hi!» is always printed correctly, but «Привет!» is not (even this forum did not allowed me to use cyrillic in
[code]
tag). I would prefer to have cyrillic letters to be printed correctly worldwide, and latin ones to be printed as gibberish except for rare cases when codepages are correctly set and matched.
-
I think this is more of a Windows-specific problem. You are creating a Windows console application I guess? From experience I know that setting a global C++ locale results in calling the library function std::setlocale which sets the global C locale (used by functions like std::atof) which on Windows also tends to adjust the codepage of the console. Imbueing a stream with a locale does not call setlocale. To get your text to be displayed correctly without interfering with the global C locale you could either manually set a codepage for your console with WinApi (I remember there being a function for setting codepages) and hope that the console will support it or use a good GUI package.
If you want to keep modifying the global locale, you could still use stringstreams imbued with a "C" locale to parse text instead of atof. That is one of the main advantages of using seperate locale objects for every stream instead of a single big locale for everything, you don't have to depend on the assumption that the current global locale is correct for your work.
-
I think this is more of a Windows-specific problem. You are creating a Windows console application I guess? From experience I know that setting a global C++ locale results in calling the library function std::setlocale which sets the global C locale (used by functions like std::atof) which on Windows also tends to adjust the codepage of the console. Imbueing a stream with a locale does not call setlocale.
That sounds plausible.
If you want to keep modifying the global locale, you could still use stringstreams imbued with a "C" locale to parse text instead of atof.
Thanks, that works for me.
-
@SAn: You can quote someone's post by clicking on "Zitieren" in the right upper corner of a post.