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();