19

Windows_setmbcp函数允许任何有效的代码页...

(不支持的 UTF-7 和 UTF-8 除外)

好的,不支持 UTF-7 是有道理的:字符具有非唯一的表示形式,这会带来复杂性和安全风险。

但为什么不是 UTF-8?

据我了解,Windows API 函数的“ANSI”版本将其参数转换为 UTF-16,调用等效的“W”函数,并将输出中的任何字符串转换为“ANSI”。这是我一直在手动做的。那么为什么 Windows 不能为我做呢?

4

4 回答 4

9

“ANSI”代码页基本上是遗留的:Windows 9X 时代。无论如何,所有现代软件都应该基于 Unicode(即 UTF-16)。

基本上,最初设计 Ansi 代码页时,甚至还没有发明 UTF-8,因此对多字节编码的支持相当随意(即大多数 Ansi 代码页都是单字节的,除了一些东亚代码页这是一个或两个字节)。当所有新开发都应该在 UTF-16 中完成时,添加对“正确”多字节编码的支持可能被认为不值得付出努力。

于 2010-06-08T06:09:45.733 回答
6

微软国际化专家迈克尔卡普兰试图在他的博客上回答这个问题。

基本上,他的解释是,即使 Windows API 函数的“ANSI”版本旨在处理不同的代码页,但从历史上看,存在一个隐含的期望,即字符编码每个代码点最多需要两个字节。UTF-8 不符合这个期望,现在改变所有这些功能需要大量的测试。

于 2014-02-03T09:42:31.383 回答
5

_setmbcp()是 VC++ RTL 函数,而不是 Win32 API 函数。它只影响 RTL 如何解释字符串。它对 Win32 APIA函数没有任何影响。当它们在W内部调用它们的对应对象时,这些A函数始终使用MultiByteToWideChar()WideCharToMultiByte()指定代码页 0 ( CP_ACP) 以使用系统默认的 Ansi 代码页进行转换。

于 2010-07-21T22:00:00.140 回答
4

原因与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-8MSVC中有一些新选项:/utf-8设置字符集,或者您也可以在 UWP 应用的 appxmanifest 中设置 ActiveCodePage 属性

自 Windows 10 内部版本 17035 以来,在引入这些选项之前,还添加了一个“测试版:使用 Unicode UTF-8 支持全球语言”复选框,用于将区域设置代码页设置为 UTF-8

Beta:使用 Unicode 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 作为代码页。

UTF-8 支持

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

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

也可以看看

于 2020-08-24T07:16:41.577 回答