1

I have this working on Visual Studio 2019 using code pages:

#include <windows.h>
#include <iostream>

int main()
{
    UINT oldcp = GetConsoleOutputCP();  
    SetConsoleOutputCP(932);      //932 = Japanese. 
                                  //1200 for little-, 1201 big-, endian UTF-16     

    DWORD used;
    WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),L"私の犬\n", 4,&used, 0);

    std::cout << "Hit enter to end."; std::cin.get();
    SetConsoleOutputCP(oldcp); 
    return 0;
}

But I am seeing from Microsoft that I should not be using code pages except to interface with legacy code -- use UTF-16 instead. I can find code pages for UTF-16 (little endian or big endian), but using them doesn't work and it's still using code pages.

So what can I use that accomplishes what my program does, but is up-to-date?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Topological Sort
  • 2,733
  • 2
  • 27
  • 54
  • Does this answer your question? [How do I print Unicode to the output console in C with Visual Studio?](https://stackoverflow.com/questions/46512441/how-do-i-print-unicode-to-the-output-console-in-c-with-visual-studio) – phuclv Mar 03 '22 at 00:59
  • Alas, no, those solutions were able to produce output that could be saved in a text file and displayed later (as I can, too), but not that will be visible in the console. – Topological Sort Mar 10 '22 at 20:13

2 Answers2

2

Set stdin and stdout to wide mode in Windows and use wcout and wcin with wide strings. You'll need to switch to a console font to support the characters and and IME to type them as well, which can be accomplished by installing the appropriate language support. You're getting that switch automatically by setting a code page, but the characters output correctly even in the "wrong" code page. If you select a font that supports the characters it will work.

#include <iostream>
#include <string>
#include <io.h>
#include <fcntl.h>

int main()
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_WTEXT);

    std::wcout << L"私の犬" << std::endl;
    std::wstring a;
    std::wcout << L"Type a string: ";
    std::getline(std::wcin, a);
    std::wcout << a << std::endl;
    getwchar();
}

Output (terminal using code page 437 but NSimSun font):

私の犬
Type a string: 马克
马克
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • 1
    I would like something that would work for users who aren't dedicated enough to install different IME's, but if this is along the way to that, great. When I ran this, I got little question-mark-in-a-box characters instead of the correct ones (私の犬). This may be because I don't know how to switch to a console font to support the characters. Can that be done in the code? Tx. – Topological Sort Mar 10 '22 at 19:53
  • @TopologicalSort To be clear, IME is for input, not output. You can also copy/paste chars that you cannot type, due to missing IME. Regarding "little question-mark-in-a-box characters", you need a font that can display these chars. What exactly is meant by "console"? Console in MS Visual Studio? Or a compiled binary running from cmd.exe? If IDE, please try again from cmd.exe. – kevinarpe May 30 '23 at 15:44
0

Technically every character encoding is a code page. To use UTF-16 you still have to specify the UTF-16 "code page". But you also need to _setmode first

_setmode(_fileno(stdout), _O_U16TEXT);
std::cout << L"私の犬\n";

But is it up-to-date? No!!! The most reasonable way to print Unicode is to use the UTF-8 code page which will make your app cross-platform and is easier to maintain. See What is the Windows equivalent for en_US.UTF-8 locale? for details on this. Basically just

  • target Windows SDK v17134 or newer, or use static linking to work on older Windows versions
  • change the code page to UTF-8
  • use the -A Win32 APIs instead of -W ones if you're calling those directly (recommended by MS for portability, as everyone else was using UTF-8 for decades)
  • set the /execution-charset:utf-8 and/or /utf-8 flags while compiling
std::setlocale(LC_ALL, ".UTF8");
std::cout << "私の犬\n";

See also Is it possible to set "locale" of a Windows application to UTF-8?

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • I don't know what Windows SDK version I have; VS just says "Windows 10 (latest version available)" -- I tried a few web pages' answers, but they do not return an answer. I'll assume "change the code page to UTF-8" is the `setlocale` cmd you provided. How do I use the -A WIn32 APIs, or set the /utf-8 flag? I searched under Command-line options for compilation and linking, but couldn't find -A or utf. Tx. – Topological Sort Mar 10 '22 at 20:10
  • 1
    You can check the Windows sdk versions installed through the Visual Studio installer. – Minxin Yu - MSFT Mar 14 '22 at 02:11
  • @TopologicalSort please read the above links to know how to use UTF-8 locale. The `-A` APIs is simply the ones ending with A. There are almost always 2 functions for each API, one for ANSI (`-A`) and the other for Unicode (Wide, ending with `-W`), for example `CreateFileA` and `CreateFileW` – phuclv Mar 14 '22 at 04:09
  • In case this answer turns out to be the solution: to check Windows sdk version, open Visual Studio Installer. Click Modify on the version being used. Under Individual Components tab, search for Windows SDK. – Topological Sort Mar 21 '22 at 13:10