I'm writing a cross-platform application in C++. All strings are UTF-8-encoded internally. Consider the following simplified code:
#include <string>
#include <iostream>
int main() {
std::string test = u8"Greek: αβγδ; German: übergr??entr?ger";
std::cout << test;
return 0;
}
On Unix systems, std::cout
expects 8-bit strings to be UTF-8-encoded, so this code works fine.
On Windows, however, std::cout
expects 8-bit strings to be in Latin-1 or a similar non-Unicode format (depending on the codepage). This leads to the following output:
Greek: ╬?╬▓╬│╬┤; German: ├£bergr├?├?entr├?ger
What can I do to make std::cout
interpret 8-bit strings as UTF-8 on Windows?
This is what I tried:
#include <string>
#include <iostream>
#include <io.h>
#include <fcntl.h>
int main() {
_setmode(_fileno(stdout), _O_U8TEXT);
std::string test = u8"Greek: αβγδ; German: übergr??entr?ger";
std::cout << test;
return 0;
}
I was hoping that _setmode
would do the trick. However, this results in the following assertion error in the line that calls operator<<
:
See Question&Answers more detail:osMicrosoft Visual C++ Runtime Library
Debug Assertion Failed!
Program: d:visual studio 2015Projectsutf8testDebugutf8test.exe File: minkernelcrtsucrtsrcappcrtstdiofputc.cpp Line: 47
Expression: ( (_Stream.is_string_backed()) || (fn = _fileno(_Stream.public_stream()), ((_textmode_safe(fn) == __crt_lowio_text_mode::ansi) && !_tm_unicode_safe(fn))))
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.