在 Visual Studio 中使用 UTF-16 代替代码页进行 I/O

发布于 2025-01-11 02:46:46 字数 764 浏览 0 评论 0原文

我使用代码页在 Visual Studio 2019 上进行此操作:

#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;
}

但我从 Microsoft 看到我 不应使用代码页,除非与遗留代码交互 - 请改用 UTF-16。我可以找到 UTF-16(小端或大端)的代码页,但使用它们不起作用并且它仍在使用代码页。

那么我可以使用什么来完成我的程序的功能,但又是最新的呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〆一缕阳光ご 2025-01-18 02:46:46

在 Windows 中将 stdin 和 stdout 设置为宽模式,并将 wcoutwcin 与宽字符串一起使用。您需要切换到控制台字体来支持字符,并使用 IME 来键入它们,这可以通过安装适当的语言支持来完成。您可以通过设置代码页自动获得该开关,但即使在“错误”的代码页中,字符也能正确输出。如果您选择支持字符的字体,它将起作用。

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

输出(终端使用代码页 437 但使用 NSimSun 字体):

私の犬
Type a string: 马克
马克

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: 马克
马克
○愚か者の日 2025-01-18 02:46:46

从技术上讲,每个字符编码都是一个代码页。要使用 UTF-16,您仍然必须指定 UTF-16“代码页”。但您还需要首先_setmode

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

但是是吗?是最新的吗? 不!!! 打印 Unicode 最合理的方法是使用 UTF-8 代码页,这将使您的应用程序跨平台并且更易于维护。有关详细信息,请参阅en_US.UTF-8 语言环境的 Windows 等效项是什么?。基本上只

  • 针对 Windows SDK v17134 或更高版本,或者使用静态链接在较旧的 Windows 版本上工作,
  • 将代码页更改为 UTF-8
  • 使用 -A code> Win32 API 而不是 -W 如果您直接调用这些 API( MS 推荐的可移植性,因为其他人几十年来都在使用 UTF-8)
  • 设置 /execution-charset:utf-8 和/或编译时的 /utf-8 标志
std::setlocale(LC_ALL, ".UTF8");
std::cout << "私の犬\n";

另请参阅是否可以将 Windows 应用程序的“区域设置”设置为 UTF -8?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文