How can I output non-ASCII text using std::wcout in Windows XP if I use MinGW w64 for compilation? Already looked a bunch of similar questions, but none of this works. _setmode(_fileno(stdout), _O_U16TEXT) returns -1, compiling with -municode does not help - the message is printed before the first non-ASCII character. (complete command: i686-w64-mingw32-g++ -mconsole -municode -static ). On the other hand, here is the code:

 int wmain() { DWORD _; std::wstring ws = L"кошка\n"; WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), ws.size(), &_, nullptr); return 0; } 

displays the message correctly, but I would like to use wcout. Maybe there is a way?

    1 answer 1

    std::wstreambuf : write your own std::wstreambuf , which would WriteConsoleW lines through WriteConsoleW and read them via ReadConsoleW . Then the objects of these classes can be placed in wcout and in wcin and then they will work with non-ASCII text correctly.

    This code can be put in a .cpp file and simply added to the project.

     #include <iostream> #include <windows.h> #include <vector> class MyWriteBuf:public std::wstreambuf{ public: MyWriteBuf(DWORD handle):std::wstreambuf(), _handle(handle){ } protected: virtual std::streamsize xsputn(const wchar_t* s, std::streamsize num) override { std::copy(s, s + num, std::back_inserter(_buffer)); return num; } virtual int sync() override { if (!_buffer.empty()) { std::wstring str(_buffer.cbegin(), _buffer.cend()); DWORD _; WriteConsoleW(GetStdHandle(_handle), str.c_str(), str.size(), &_, nullptr); _buffer.clear(); } return 0; } private: DWORD _handle; std::vector<wchar_t> _buffer; }; class MyReadBuf:public std::wstreambuf{ public: MyReadBuf():std::wstreambuf(){ setg(_chars, _chars+BUF_SIZE, _chars+BUF_SIZE); } protected: int_type underflow() override { DWORD num_read; ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), _chars, BUF_SIZE, &num_read, nullptr); setg(_chars, _chars, _chars+num_read); return (int_type)(_chars[0]); } private: const static uint8_t BUF_SIZE=10; wchar_t _chars[BUF_SIZE]; }; int static_init(){ MyWriteBuf *buf_out=new MyWriteBuf(STD_OUTPUT_HANDLE); MyWriteBuf *buf_err=new MyWriteBuf(STD_ERROR_HANDLE); MyReadBuf *buf_in=new MyReadBuf(); std::wcout.rdbuf(buf_out); std::wcerr.rdbuf(buf_err); std::wcin.rdbuf(buf_in); return 0; } int global_t=static_init();