Windows_setmbcp
函数允许任何有效的代码页...
(不支持的 UTF-7 和 UTF-8 除外)
好的,不支持 UTF-7 是有道理的:字符具有非唯一的表示形式,这会带来复杂性和安全风险。
但为什么不是 UTF-8?
据我了解,Windows API 函数的“ANSI”版本将其参数转换为 UTF-16,调用等效的“W”函数,并将输出中的任何字符串转换为“ANSI”。这是我一直在手动做的。那么为什么 Windows 不能为我做呢?
“ANSI”代码页基本上是遗留的:Windows 9X 时代。无论如何,所有现代软件都应该基于 Unicode(即 UTF-16)。
基本上,最初设计 Ansi 代码页时,甚至还没有发明 UTF-8,因此对多字节编码的支持相当随意(即大多数 Ansi 代码页都是单字节的,除了一些东亚代码页这是一个或两个字节)。当所有新开发都应该在 UTF-16 中完成时,添加对“正确”多字节编码的支持可能被认为不值得付出努力。
微软国际化专家迈克尔卡普兰试图在他的博客上回答这个问题。
基本上,他的解释是,即使 Windows API 函数的“ANSI”版本旨在处理不同的代码页,但从历史上看,存在一个隐含的期望,即字符编码每个代码点最多需要两个字节。UTF-8 不符合这个期望,现在改变所有这些功能需要大量的测试。
_setmbcp()
是 VC++ RTL 函数,而不是 Win32 API 函数。它只影响 RTL 如何解释字符串。它对 Win32 APIA
函数没有任何影响。当它们在W
内部调用它们的对应对象时,这些A
函数始终使用MultiByteToWideChar()
并WideCharToMultiByte()
指定代码页 0 ( CP_ACP
) 以使用系统默认的 Ansi 代码页进行转换。
原因与jamesdlin 的答案和下面的评论中所说的完全一样:MBCS 与 Windows 中的 DBCS 相同,并且某些功能不适用于长度超过 2 个字节的字符
微软表示,UTF-8 语言环境可能会破坏某些函数,因为它们被编写为假设每个字符使用不超过 2 个字节的多字节编码,因此具有更多字节的代码页,如 UTF-8(以及 GB 18030、cp54936)不能设置为语言环境。
https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows#UTF-8
因此,UTF-8 在读/写等功能中被允许,但在用作语言环境时则不允许
然而微软终于解决了这个问题,所以现在我们可以使用 UTF-8 作为 locale。事实上,MS 甚至开始-A
再次推荐 ANSI API ( ),而不是像以前那样推荐 Unicode ( -W
) 版本。/execution-charset:utf-8
MSVC中有一些新选项:/utf-8
设置字符集,或者您也可以在 UWP 应用的 appxmanifest 中设置 ActiveCodePage 属性
自 Windows 10 内部版本 17035 以来,在引入这些选项之前,还添加了一个“测试版:使用 Unicode UTF-8 支持全球语言”复选框,用于将区域设置代码页设置为 UTF-8
要打开该对话框,请打开开始菜单,键入“区域”并选择区域设置 > 其他日期、时间和区域设置 > 更改日期、时间或数字格式 > 管理
启用后,您可以调用setlocale()
以更改为 UTF-8 语言环境:
从 Windows 10 build 17134(2018 年 4 月更新)开始,通用 C 运行时支持使用 UTF-8 代码页。这意味着
char
传递给 C 运行时函数的字符串将需要 UTF-8 编码的字符串。要启用 UTF-8 模式,请在使用setlocale
. 例如,setlocale(LC_ALL, ".utf8")
将使用当前默认的 Windows ANSI 代码页 (ACP) 作为语言环境,使用 UTF-8 作为代码页。
您也可以在较旧的 Windows 版本中使用它
要在 Windows 10 之前的操作系统(例如 Windows 7)上使用此功能,您必须使用应用程序本地部署或使用 Windows SDK 版本 17134 或更高版本进行静态链接。对于 17134 之前的 Windows 10 操作系统,仅支持静态链接。