为什么不允许UTF-8作为“ANSI”代码页?

时间:2010-06-08 06:04:48

标签: windows utf-8 mbcs

Windows _setmbcp功能允许任何有效的代码页...

  

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

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

但为什么不用UTF-8?

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

4 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:5)

_setmbcp()是VC ++ RTL函数,而不是Win32 API函数。它只影响RTL解释字符串的方式。它对Win32 API A函数没有任何影响。当他们在内部呼叫他们的W对应人时,A函数始终使用MultiByteToWideChar()WideCharToMultiByte()指定代码页0(CP_ACP)来使用系统默认的Ansi代码页转换。

答案 2 :(得分:4)

来自微软的国际化专家Michael Kaplan试图回答这个问题on his blog

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

答案 3 :(得分:1)

原因与jamesdlin's answers中的内容及其下方的注释完全相同:MBCS is the same as DBCS in Windows和某些函数不适用于超过2个字节的字符

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

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

因此,在读/写等功能中允许使用UTF-8,但在用作语言环境时则不允许使用


但是Microsoft终于解决了该问题,现在我们可以use UTF-8 as a locale了。实际上,MS甚至开始再次推荐ANSI API(-A),而不是像以前那样推荐Unicode(-W)版本。 MSVC中有一些新选项:/execution-charset:utf-8/utf-8用于设置字符集,或者您也可以在UWP应用的appxmanifest中设置ActiveCodePage属性

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

Beta: Use Unicode UTF-8 for worldwide language support

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

启用后,您可以调用setlocale()更改为UTF-8语言环境:

Universal C Runtime从Windows 10内部版本17134(2018年4月更新)开始,支持使用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或使用Windows SDK版本17134或更高版本进行静态链接。对于17134之前的Windows 10操作系统,仅支持静态链接。

另请参见