Windows 对其 Unicode 数据类型使用啥 Unicode 编码(UTF-8、UTF-16 等)?

Posted

技术标签:

【中文标题】Windows 对其 Unicode 数据类型使用啥 Unicode 编码(UTF-8、UTF-16 等)?【英文标题】:What unicode encoding (UTF-8, UTF-16, other) does Windows use for its Unicode data types?Windows 对其 Unicode 数据类型使用什么 Unicode 编码(UTF-8、UTF-16 等)? 【发布时间】:2012-11-21 18:40:09 【问题描述】:

相同的 Unicode(标准化)table 有不同的编码。例如对于 UTF-8 编码 A corresponds to 0x0041 但对于 UTF-16 编码,相同的 A 是 represented as 0xfeff0041

从brilliant article 我了解到,当我使用 C++ 为 Windows 平台编程并处理 Unicode 时,我应该知道它以 2 个字节表示。但它没有说明任何关于编码的内容。 (即使它说 x86 CPU 是 little-endian,所以我知道这两个字节是如何存储在内存中的。)但我也应该知道 Unicode 的编码,以便我有关于符号如何存储在内存中的完整信息。 C++/Windows 程序员有固定的 Unicode 编码吗?

【问题讨论】:

A 在 UTF-16 中表示为 0xfeff0041。它是 UTF-8 中的 0x41 和 UTF-16 中的 0x0041 fileformat.info/info/charset/UTF-16/list.htm 这是我的信息来源,正如我已经提到的。那么它是如何存储的呢? 您的来源有误。所有这些值前面都不应该有feff0xFEFF 用作 UTF-16 BOM。 @Narek 0xfeff 是字节顺序标记。该表只是告诉您以下两个字节的顺序。如果您转到the page for A,您将看到 UTF-8 编码为 0x41,UTF-16 编码为 0x0041。 UTF-8 根据值使用 1、2、3 或 4 个字节对 Unicode 代码点进行编码。 UTF-16 使用 2 或 4 个字节对 Unicode 代码点进行编码,具体取决于值。只有 ASCII 代码点 (0x00-0x7F) 在 UTF-8 和 UTF-16 编码中具有相同的值。否则,代码点 0x80 和更高版本的编码方式不同。 【参考方案1】:

存储在 Windows 内存中的值始终为 UTF-16 little-endian。但这不是您在谈论的内容-您正在查看文件内容。 Windows 本身并没有指定文件的编码,而是将其留给各个应用程序。

您在文件开头看到的 0xfe 0xff 是Byte Order Mark or BOM。它不仅表明该文件很可能是 Unicode,而且还告诉您 Unicode 编码的变体。

0xfe 0xff      UTF-16 big-endian
0xff 0xfe      UTF-16 little-endian
0xef 0xbb 0xbf UTF-8

除非您知道它是如何编写的,否则应该假定没有 BOM 的文件是 8 位字符。这仍然不能告诉您它是 UTF-8 还是其他 Windows 字符编码,您只需要猜测即可。

您可以使用记事本作为示例来说明如何完成此操作。如果文件有 BOM,则记事本会读取它并适当地处理内容。否则,您必须使用“编码”下拉列表自己指定编码。

编辑:Windows 文档没有更具体地说明编码的原因是 Windows 是 Unicode 的早期采用者,当时有 only one encoding of 16 bits per code point。当 65536 个代码点被确定为不足时,发明了代理对作为扩展范围的一种方式,UTF-16 诞生了。微软已经在使用 Unicode 来指代他们的编码并且从未改变过。

【讨论】:

“存储在 Windows 内存中的值始终是 UTF-16 little-endian。” 这就是我需要的!非常感谢!只是我想知道它是否有记录? @Narek,这是一个参考:msdn.microsoft.com/en-us/library/windows/desktop/…。引用:“通常,Windows 应用程序应在内部使用 UTF-16,仅将其转换为必须使用另一种格式的接口上的“薄层”的一部分。”它是 little-endian 的事实不是 Windows 指定的,而是它是一个 little-endian Intel 处理器的事实。 谢谢马克,真的很有帮助! @RemyLebeau,这篇文章提出了记事本猜测的情况,以及在找不到 BOM 时可以预期的情况。我的建议是不要猜测,而是让用户决定,记事本(至少在 Win7 中)也为您提供了该选项。 再一次,为了狡辩,存储在内存中的 Windows 的值总是 UTF-16 little endian 是不正确的。您可以在任何编码、内存、Windows 应用程序中存储您想要的任何值。由每个访问该内存的程序决定如何处理它。许多 Windows API 函数使用 UTF-16,但这只是一种 API。

以上是关于Windows 对其 Unicode 数据类型使用啥 Unicode 编码(UTF-8、UTF-16 等)?的主要内容,如果未能解决你的问题,请参考以下文章

在 MFC windows 应用程序中删除 unicode

使用C#以二进制序列化字符串,并使用C ++对其进行反序列化

在SQL数据类型中,Unicode数据类型和非Unicode数据类型具体有啥区别?

SQL 中的 Unicode 数据类型

如何审核我的 Windows 应用程序以进行正确的 Unicode 处理?

我可以将非 unicode 数据类型写入 Excel 吗?