en_US.UTF-8 语言环境的 Windows 等效项是啥?

Posted

技术标签:

【中文标题】en_US.UTF-8 语言环境的 Windows 等效项是啥?【英文标题】:What is the Windows equivalent for en_US.UTF-8 locale?en_US.UTF-8 语言环境的 Windows 等效项是什么? 【发布时间】:2011-05-18 11:52:52 【问题描述】:

如果我想在 Windows 上进行以下工作,正确的语言环境是什么以及如何检测它是否实际存在: Does this code work universaly, or is it just my system?

【问题讨论】:

【参考方案1】:

尽管对命名语言环境没有很好的支持,但 Visual Studio 2010 确实包含 C++11 所需的 UTF-8 转换方面:std::codecvt_utf8 用于 UCS2,std::codecvt_utf8_utf16 用于 UTF-16:

#include <fstream>
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
void prepare_file()

    // UTF-8 data
    char utf8[] = '\x7a',                       // latin small letter 'z' U+007a
                   '\xe6','\xb0','\xb4',         // CJK ideograph "water"  U+6c34
                   '\xf0','\x9d','\x84','\x8b'; // musical sign segno U+1d10b
    std::ofstream fout("text.txt");
    fout.write(utf8, sizeof utf8);

void test_file_utf16()

    std::wifstream fin("text.txt");
    fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf8_utf16<wchar_t>));
    std::cout << "Read from file using UTF-8/UTF-16 codecvt\n";
    for(wchar_t c; fin >> c; )
        std::cout << std::hex << std::showbase << c << '\n';

void test_file_ucs2()

    std::wifstream fin("text.txt");
    fin.imbue(std::locale(fin.getloc(), new std::codecvt_utf8<wchar_t>));
    std::cout << "Read from file using UTF-8/UCS2 codecvt\n";
    for(wchar_t c; fin >> c; )
        std::cout << std::hex << std::showbase << c << '\n';

int main()

    prepare_file();
    test_file_utf16();
    test_file_ucs2();

此输出,在我的 Visual Studio 2010 EE SP1 上

Read from file using UTF-8/UTF-16 codecvt
0x7a
0x6c34
0xd834
0xdd0b
Read from file using UTF-8/UCS2 codecvt
0x7a
0x6c34
0xd10b
Press any key to continue . . .

【讨论】:

【参考方案2】:

基本上你倒霉了:http://www.siao2.com/2007/01/03/1392379.aspx

【讨论】:

@Nemanja Trifunovic:这正是不是博客的重点。对于像 MessageBoxW 这样的每个 UTF-16 API,都有一个“ANSI”变体 MessageBoxA,它将使用当前的“ANSI”代码页进行 8 位到 UTF-16 的转换。但是,您不能使用 UTF-8 作为当前的“ANSI”代码页。但是,MultiByteToWideChar 不使用当前的 ANSI 代码页。它的第一个参数是要使用的代码页,there UTF-8 (65001) 是允许的。 @MSalters:博客的重点是代码页 65001 不能是 ACP,这意味着它不能用作 C++ 标准库语言环境。我提到的 UTF-8 UTF-16 转换不是博客的重点,而是我对如何在 Windows 上使用 UTF-8 的问题的回答。更简短的回答是:不要在 Windows 上使用 C++ 标准库进行 IO。 @Let_Me_Be:基本上,这归结为 Windows 上的 wchar_t 专门定义为 16 位类型。 C(和 C++)标准要求 wchar_t 能够保存 all 支持的编码中的 any 有效字符。但是没有办法将所有的 Unicode 字符编码为 16 位 - 就是无法做到。因此,Windows C 和 C++ 库实际上支持任何类型的 Unicode。如果你想在 Windows 上使用 Unicode,你必须跳出 C 和 C++ 库。是的,这很愚蠢,但是您对 Microsoft 有什么期望? :P @Let_Me_Be:您混淆了 16 位 wchar_t 和 UTF-16。它们不是同一件事。 UTF-8 和 UTF-16 是编码所有 Unicode 代码点的两种不同方式(其中 far 不仅仅是 65535)。您至少需要 24 位来表示所有 1,000,000 多个 Unicode 代码点。 UTF-16 中的“16”not 表示所有字符都只能使用 16 位表示(例如,某些 Unicode 字符需要 32 位 [两个 16 位 代码单元 ]使用 UTF-16 编码时)。但是 C++ 库需要 wchar_t 才能唯一地表示 每个 支持的字符。 @Let_Me_Be:我确实阅读了您的链接问题,但您似乎没有理解那里的正确答案。部分(甚至全部)Windows API 可以将 wchar_t 字符串解释为 UTF-16 编码数据,但C 和 C++ 库 。如果他们这样做了,那么您可以使用 UTF-8 作为 C 和 C++ 库的语言环境。但是,你不能。这就是您的问题的答案;)【参考方案3】:

在过去,UTF-8(和其他一些代码页)不允许作为系统语言环境,因为

Microsoft 表示,UTF-8 语言环境可能会破坏某些函数,因为它们被编写为假设多字节编码每个字符使用不超过 2 个字节,因此代码页具有更多字节,例如 UTF-8(以及 GB 18030、cp54936 ) 无法设置为语言环境。

https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows#UTF-8

不过,微软逐渐引入了UTF-8 locale support,并开始再次推荐 ANSI API (-A),而不是像以前那样的 Unicode (-W) 版本

直到最近,Windows 一直强调“Unicode”-W 变体而不是 -A API。但是,最近的版本使用 ANSI 代码页和 -A API 作为向应用程序引入 UTF-8 支持的一种方式。如果为 UTF-8 配置 ANSI 代码页,则-A API 以 UTF-8 运行。此模型的优势在于支持使用-A API 构建的现有代码,无需任何代码更改。

-A vs. -W APIs


首先,他们添加了一个“Beta:使用 Unicode UTF-8 支持全球语言”复选框,因为 Windows 10 Insider build 17035 用于将语言环境代码页设置为 UTF-8

要打开该对话框,请打开开始菜单,输入“区域”并选择区域设置 > 其他日期、时间和区域设置 > 更改日期、时间或数字格式 > 管理

启用后,您可以像往常一样拨打setlocal

从 Windows 10 build 17134(2018 年 4 月更新)开始,通用 C 运行时支持使用 UTF-8 代码页。这意味着传递给 C 运行时函数的 char 字符串将需要 UTF-8 编码的字符串。要启用 UTF-8 模式,请在使用 setlocale 时使用“UTF-8”作为代码页。例如,setlocale(LC_ALL, ".utf8") 将使用当前默认的 Windows ANSI 代码页 (ACP) 作为语言环境,使用 UTF-8 作为代码页。

UTF-8 Support

您也可以在旧的 Windows 版本中使用它

要在 Windows 10 之前的操作系统(例如 Windows 7)上使用此功能,您必须使用 app-local deployment 或使用版本 17134 或更高版本的 Windows SDK 进行静态链接。对于 17134 之前的 Windows 10 操作系统,仅支持静态链接。


在 2019 年后期,他们增加了程序使用 UTF-8 语言环境的功能,甚至无需在上面设置 UTF-8 beta 标志。使用 MSVC 编译时可以使用 /execution-charset:utf-8/utf-8 选项,或者在 appxmanifest 中设置 ActiveCodePage 属性

【讨论】:

新功能的精彩回顾!令人惊讶的是,他们花了这么长时间才说“让我们在 C 字符串中使用 utf-8”。 /utf-8 选项似乎与复选框无关。它设置了二进制文件的执行和源字符集,但我可能错了。【参考方案4】:

根据MSDN,它将被命名为“english_us.65001”。但是代码页 65001 在 Windows 上有些不稳定。

【讨论】:

你能否对“有点片状”发表更多评论? @Let_Me_Be:我无法比google.com/search?q=site%3Ablogs.msdn.com+65001总结得更好 @MSalters 很抱歉,但我找不到任何最新且足够详细的内容。我从阅读的简短博客文章中了解到,Windows 根本不支持 UTF-8(这没有任何意义)。 @Let_Me_Be:它没有隐式支持。你不能打电话给MessageBoxA("Hellö")。但是,它有明确的支持:MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8input.c_str(), ... @Let_Me_Be:所有这些答案试图说明的是 Windows 上没有 utf-8 语言环境。

以上是关于en_US.UTF-8 语言环境的 Windows 等效项是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Ubuntu系统终端环境支持中文的方法

修改Linux系统语言

redhat6.2 中文环境改成英文环境

Debian下Cannot set LC_CTYPE to default locale: No such file or directory解决方法

Debian下Cannot set LC_CTYPE to default locale: No such file or directory解决方法

修改CentOS7,修改默认语言环境