title: Can std::cout work with UTF-8 on Windows?
body: <p>I want to make <code>std::cout</code> print an UTF-8 literal. This seems to be an easy task with gcc, but an extremely difficult one with Windows.</p>
  
  <p>The code that I'm trying to get to work is:</p>
  
  <pre><code>std::cout &lt;&lt; "Ελληνικά Русский 你好";
  </code></pre>
  
  <p>Environment:</p>
  
  <ul>
  <li>Windows 10, Visual Studio 2015</li>
  <li>Default encoding: 1251</li>
  <li>Console encoding: 866</li>
  <li>Source encoding: UTF-8 with BOM</li>
  </ul>
  
  <p>Requirements:</p>
  
  <ul>
  <li>No changes to the line of code itself must be made</li>
  <li>Full Unicode range support</li>
  <li>Some setup code may be added in the beginning of <code>main()</code></li>
  </ul>
  
  <p>What I've tried:</p>
  
  <ul>
  <li><code>#pragma execution_character_set("utf-8")</code></li>
  <li><code>SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8);</code></li>
  <li>Set console font to Lucida Console system-wide</li>
  <li><code>Use Unicode character set</code> in project properties</li>
  <li>Setup code from <a href="https://alfps.wordpress.com/2011/11/22/unicode-part-1-windows-console-io-approaches/" rel="nofollow noreferrer">this</a> blog</li>
  </ul>
  
  <p>Nothing helped, and no StackOverflow answer solved the problem.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>To get Unicode <strong>partially</strong> working, do the following:</p>
  
  <ul>
  <li>Call <code>initStreams()</code> from the listing below at the start</li>
  <li>Turn on <code>Use Unicode Character Set</code> in Project Settings</li>
  <li>Add <code>/utf-8</code> option</li>
  </ul>
  
  <p>Not working:</p>
  
  <ul>
  <li><code>wprintf</code></li>
  <li><code>cin</code>/<code>wcin</code></li>
  <li>Chinese characters</li>
  </ul>
  
  <p><code>initStreams()</code> implementation:</p>
  
  <pre><code>#include &lt;cassert&gt;         // assert
  #include &lt;codecvt&gt;          // std::codecvt_utf8 (C++11)
  #include &lt;stdexcept&gt;        // std::exception
  #include &lt;streambuf&gt;        // std::basic_streambuf
  #include &lt;iostream&gt;         // std::cout, std::endl
  #include &lt;locale&gt;           // std::locale
  #include &lt;memory&gt;           // std::unique_ptr (C++11)
  
  #undef  UNICODE
  #define UNICODE
  #undef  STRICT
  #define STRING
  #include &lt;windows.h&gt;    // MultiByteToWideChar
  
  class OutputForwarderBuffer : public std::basic_streambuf&lt;char&gt;
  {
  public:
      using Base = std::basic_streambuf&lt;char&gt;;
      using Traits = Base::traits_type;
      using StreamBuffer = std::basic_streambuf&lt;char&gt;;
      using WideStreamBuffer = std::basic_streambuf&lt;wchar_t&gt;;
      using Base::int_type;
      using Base::char_type;
  
      OutputForwarderBuffer(
          StreamBuffer&amp; existingBuffer,
          WideStreamBuffer* pWideStreamBuffer
      )
          : Base(existingBuffer)
          , pWideStreamBuffer_(pWideStreamBuffer)
      {
      }
  
      OutputForwarderBuffer(OutputForwarderBuffer const&amp;) = delete;
      void operator=(OutputForwarderBuffer const&amp;) = delete;
  
  protected:
      std::streamsize xsputn(char const* s, std::streamsize n) override
      {
          if (n == 0) { return 0; }
  
          int const sourceSize = static_cast&lt;int&gt;(n);
          int const destinationSize = MultiByteToWideChar(CP_UTF8, 0, s, sourceSize, nullptr, 0);
          wideCharBuffer_.resize(static_cast&lt;size_t&gt;(sourceSize));
  
          int const nWideCharacters = MultiByteToWideChar(CP_UTF8, 0, s, sourceSize, &amp;wideCharBuffer_[0], destinationSize);
          assert(nWideCharacters &gt; 0 &amp;&amp; nWideCharacters == destinationSize);
  
          return pWideStreamBuffer_-&gt;sputn(&amp;wideCharBuffer_[0], destinationSize);
      }
  
      int_type overflow(int_type c) override
      {
          bool const cIsEOF = Traits::eq_int_type(c, Traits::eof());
          int_type const failureValue = Traits::eof();
          int_type const successValue = (cIsEOF ? Traits::not_eof(c) : c);
  
          if (!cIsEOF) {
              char_type const ch = Traits::to_char_type(c);
              std::streamsize const nCharactersWritten = xsputn(&amp;ch, 1);
  
              return (nCharactersWritten == 1 ? successValue : failureValue);
          }
          return successValue;
      }
  
  private:
      WideStreamBuffer* pWideStreamBuffer_;
      std::wstring wideCharBuffer_;
  };
  
  void setUtf8Conversion(std::basic_ios&lt;wchar_t&gt;&amp; stream)
  {
      stream.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8_utf16&lt;wchar_t&gt;()));
  }
  
  bool isConsole(HANDLE streamHandle)
  {
      DWORD consoleMode;
      return !!GetConsoleMode(streamHandle, &amp;consoleMode);
  }
  
  bool isConsole(DWORD stdStreamId)
  {
      return isConsole(GetStdHandle(stdStreamId));
  }
  
  void initStreams()
  {
      SetConsoleCP(CP_UTF8);
      SetConsoleOutputCP(CP_UTF8);
  
      setUtf8Conversion(std::wcout);
      setUtf8Conversion(std::wcerr);
      setUtf8Conversion(std::wclog);
  
      static OutputForwarderBuffer coutBuffer(*std::cout.rdbuf(), std::wcout.rdbuf());
      static OutputForwarderBuffer cerrBuffer(*std::cerr.rdbuf(), std::wcerr.rdbuf());
      static OutputForwarderBuffer clogBuffer(*std::clog.rdbuf(), std::wclog.rdbuf());
  
      std::cout.rdbuf(&amp;coutBuffer);
      std::cerr.rdbuf(&amp;cerrBuffer);
      std::clog.rdbuf(&amp;clogBuffer);
  }
  </code></pre>