I am trying to convert a single wchar_t to uppercase. In theory it should work as shown below, in practice it does not. I have no idea what I am doing wrong. Any ideas?
Output is:
T
T
?
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include <locale>
#include <string>
int main ( )
{
std::locale loc ( "en_US.UTF-8" );
//std::locale loc ( "de_DE.utf8" ); // I also tried this
std::wcout.imbue ( loc );
std::wcout << std::toupper<wchar_t> ( L't', loc ) << L'\n';
std::wcout << std::use_facet< std::ctype<wchar_t> >(loc).toupper
( L't' ) << L'\n';
std::wcout << std::toupper<wchar_t> ( L'ä', loc ) << L'\n';
std::wcout << std::use_facet< std::ctype<wchar_t> >(loc).toupper
( L'ä' ) << L'\n';
return 0;
}
The problem with the standard C++ locale library is that it does not define any locales (other than the old 'C' locale). Hence, anything you plug-in is system-dependent. (Fortunately, Linux systems seem to follow a pretty good standard, but other systems do not.)
Also, wcout does indeed narrow() the nice Unicode characters into whatever single-byte version your system takes. Frankly, it does a really bad job.
Alas, I don't yet know what to tell you besides, skip the C++ stuff and use a library like iconv or ICU, or your OS-specific unicode APIs.
Thanks everybody. Indeed, it's a problem of std::wcout (I know, I should have checked this;)). The conversion works like a charm as the output of line 14 shows. But it is even possible to get the correct output through std::wcout using the code in line 7 (thanks to Ralf Goertz for pointing me to this solution).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include <iostream>
#include <locale>
#include <string>
int main ( )
{
std::ios_base::sync_with_stdio(false);
std::locale loc ( "en_US.UTF-8" );
std::wcout.imbue ( loc );
int T = (int)std::toupper<wchar_t> ( L't', loc );
int T2 = (int)L't';
int A = (int)std::toupper<wchar_t> ( L'ä', loc );
int A2 = (int)L'ä';
std::wcout << T << " " << T2 << " " << A << " " << A2 << std::endl;
std::wcout << L'ä' << L' ' << L'o' << std::endl;
return 0;
}