Note that you're using C streams. C streams have a very special quality called "orientation". A stream is either unoriented, wide, or narrow. Orientation is decided by the first output made to any particular stream (see http://en.cppreference.com/w/cpp/io/c for a summary of C I/O streams)
In your case, stdout
starts out unoriented, and by executing the first printf
, you're setting it narrow. Once narrow, it's stuck narrow, and wprintf
fails (check its return code!). The only way to change a C stream is to freopen
it, which doesn't quite work with stdout. That's why 3 and 4 didn't print.
The differences between 1 and 3 is that 1 is a narrow output function which is using narrow string conversion specifier %s: it reads bytes from the char array and sends bytes into a byte stream. 3 is a wide output function with a narrow string conversion specifier %s: it first reads bytes from the char array and mbtowc
s them into wchar_t
s, then sends wchar_t
s into a wide stream, which then wctomb
s them into bytes or multibyte sequences that are then pushed into the standard out with a write
Finally, if widestr is in utf16, you must be using Windows, and all bets are off; there is very little support for anything beyond ASCII on that platform. You may as well give in and use WinAPI (you can get by with standard C++11 for some Unicode things, and even do this C output, with magic words _setmode(_fileno(stdout), _O_U16TEXT);
, that's been discussed enough times)
%ls
is the most portable way to print awchar_t
string and works from bothprintf
andwprintf
. You should avoid all use of%S
because the Visual C++ interpretation of it is the exact opposite of the C99/C++11 standard. – Hyperbolism