Printing wide characters to narrow streams is not supported and doesn't work at all. (It "works" but the result is not what you want).
Printing multibyte narrow strings to wide streams is not supported and doesn't work at all. (It "works" but the result is not what you want).
On a Unicode-ready system, std::cout << "\u2654"
works as expected. So does std::cout << u8"\u2654"
. Most properly set up Unix-based operating systems are Unicode-ready.
On a Unicode-ready system, std::wcout << L'\u2654'
should work as expected if you set up your program locale properly. This is done with this call:
::setlocale(LC_ALL, "");
or this
::std::locale::global(::std::locale(""));
Note "should"; with some compilers/libraries this method may not work at all. It's a deficiency with these compilers/libraries. I'm looking at you, libc++. It may or may not officially be a bug, but I view it as a bug.
You should really set up your locale in all programs that wish to work with Unicode, even if this doesn't appear necessary.
Mixing cout
and wcout
in the same program does not work and is not supported.
std::wcout << U'\u2654'
does not work because this is mixing a wchar_t
stream with a char32_t
character. wchar_t
and char32_t
are different types. I guess a properly set up std::basic_stream<char32_t>
would work with char32_t
strings, bit the standard library doesn't provide any.
char32_t
based strings are good for storing and processing Unicode code points. Do not use them for formatted input and output directly. std::wstring_convert can be used to convert them back and forth.
TL;DR work with either std::stream
s and std::string
s, or (if you are not on libc++) std::wstream
s and std::wstring
s.