Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 为什么不是';t允许UTF-8作为;美国国家标准协会;代码页?_Windows_Utf 8_Locale_Codepages_Mbcs - Fatal编程技术网

Windows 为什么不是';t允许UTF-8作为;美国国家标准协会;代码页?

Windows 为什么不是';t允许UTF-8作为;美国国家标准协会;代码页?,windows,utf-8,locale,codepages,mbcs,Windows,Utf 8,Locale,Codepages,Mbcs,Windows函数允许任何有效的代码页 (不支持UTF-7和UTF-8除外) 好的,不支持UTF-7是有道理的:字符具有非唯一表示,这会带来复杂性和安全风险 但是为什么不是UTF-8呢 据我所知,Windows API函数的“ANSI”版本将其参数转换为UTF-16,调用等效的“W”函数,并将输出中的任何字符串转换为“ANSI”。这是我一直在做的手工。那么为什么Windows不能为我做到这一点呢?ANSI代码页基本上是传统的:Windows 9X时代。无论如何,所有现代软件都应该是基于Unico

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

(不支持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中完成时,添加对“正确”多字节编码的支持可能被认为是不值得的。

\u setmbcp()
是VC++RTL函数,而不是Win32 API函数。它只影响RTL解释字符串的方式。它对Win32 API
A
函数没有任何影响。当它们在内部调用它们的
W
对应项时,
A
函数总是使用
MultiByteToWideChar()
WideCharToMultiByte()
指定代码页0(
CP\u ACP
)来使用系统默认的Ansi代码页进行转换,我试图回答这个问题


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

原因与中所述及其下面的注释完全相同:有些函数不能处理长度超过2字节的字符

微软表示,UTF-8区域设置可能会破坏某些函数,因为这些函数的编写假定多字节编码每个字符使用的字节数不超过2个,因此,UTF-8(以及GB 18030、cp54936)等字节数更多的代码页不能设置为区域设置

因此,UTF-8在读/写之类的函数中是允许的,但在用作区域设置时则不允许


然而,微软终于解决了这个问题,所以现在我们可以了。事实上,微软甚至开始再次推荐ANSI API(
-A
),而不是像以前那样推荐Unicode(
-W
)版本。MSVC中有一些新选项:和设置字符集,或者您也可以在UWP应用程序的appxmanifest中设置ActiveCodePage属性

自从Windows 10 insider build 17035引入这些选项之前,还添加了一个“Beta:使用Unicode UTF-8获得全球语言支持”复选框,用于将区域设置代码页设置为UTF-8

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

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

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

您也可以在较旧的Windows版本中使用此功能

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

另见

我同意所有新开发都应该使用Unicode。但我有理由建议使用UTF-8而不是UTF-16。(1) 我的团队在任何人对此不屑一顾之前就编写了一百万行非Unicode代码,现在要将所有基于字符的字符串更改为基于wchar_t的字符串将是一项巨大的努力。(2) 我们计划将我们的产品移植到Linux,在Linux上UTF-8是首选。从Windows版本1903(2019年5月更新)开始,您知道CP65001是Windows的UTF-8名称吗?虽然在
WriteFile()
中有一些bug,但它没有很好的文档记录,但是你可以在很多地方使用它。请参阅我在上面发布的:Windows XP和更高版本:GB18030简体中文(4字节)。你发布的参考说明是:“支持称为双字节字符集的多字节字符集(MBCS)(DBCS)在所有平台上。“注意,称为DBCS的表单是MBCS的子集。这是针对“所有平台”的。请参阅页面下方的“在启用MBCS的Windows操作系统版本上运行时,[工具]完全启用MBCS。”@evoskuil是的,CP_UTF7和CP_UTF8已经存在很长一段时间了。但是,它们不能用作默认代码页。它们仅用于
MultiByteToWideChar
/
WideCharToMultiByte
。是的,DBCS是MBCS的一种形式,但在我引用的页面的更下方,它明确地指出“MBCS始终表示DBCS。不支持大于2字节的字符集。”在上,它表示:“对于MBCS,字符大小可以是1或2字节。”@evoskuil是的,当然可以使用
NextChar
支持任意数量字节的代码点