38

我对编码不是很专业,但这是我认为我知道的(尽管它可能是错误的):

  1. ASCII 是一种 7 位、固定长度的编码,您可以在 ASCII 图表中找到字符。
  2. UTF8 是一种 8 位的可变长度编码。所有字符都可以用 UTF8 编写。
  3. UCS-2 LE/BE 是固定长度的 16 位编码,支持最常见的字符。
  4. UTF-16 是一种 16 位的可变长度编码。所有字符都可以用 UTF16 书写。

以上这些都是正确的吗?

现在,对于问题:

  1. Windows“A”函数(如SetWindowTextA)是否接收 ASCII 字符串?还是“多字节字符串”(下面有更多问题)?
  2. Windows "W" 函数接受 UTF-16 字符串还是 UCS-2 字符串?我以为他们接受 UCS-2,但名字让我感到困惑。
  3. WideCharToMultiByte中,Microsoft 使用“宽字符串”一词来表示 UTF-16。在这种情况下,什么被认为是“多字节字符串”?UTF-8?
  4. LPWSTR“宽字符串”吗?我会说它是,但是,那不是意味着它是 UTF-16 吗?这是否意味着它可以用来显示,比如说,4 字节字符?如果不是,那么...显示 4 字节字符是不可能的吗?(Windows 似乎没有这些 API。)
  5. WideCharToMultiByte的超集的功能是wcstombs, 并且它们都适用于相同类型的字符串吗?或者说,一个在 UTF-16 上工作,而另一个在 UCS-2 上工作?
  6. 文件路径是 UTF-16 还是 UCS-2?我知道 Windows 将其视为 Microsoft 文档中的“不透明字符数组”,但根据 C 函数的标准,例如fwprintf,是否有任何标准化编码?
  7. 什么是“ANSI”编码?这甚至是一个正确的术语吗?它与 ASCII 有什么关系?
  8. (我还有更多问题,但这已经足够了......我还是忘记了其中一些......)

这些问题很多,因此任何有关所有这些连接方式的解释链接(除了阅读 Unicode 标准,这对 Windows API 没有帮助)也将不胜感激。

谢谢!

4

4 回答 4

31

以上这些都是正确的吗?

是的,如果您不假设存在未以 Unicode 编码的字符(对于大多数实际应用程序,这个假设很好)。

Windows“A”函数(如 SetWindowTextA)是否接收 ASCII 字符串?还是“多字节字符串”(下面有更多问题)?

它们采用以当前“ANSI”/MBCS/legacy 编码进行编码的字节字符串(即,其代码单元为字节的字符串,在 Windows 上始终为八位字节)。“ANSI”是这些编码的历史术语,但不正确。对于西方 Windows 系统,此编码通常为 Windows-1252。

Windows "W" 函数接受 UTF-16 字符串还是 UCS-2 字符串?我以为他们接受 UCS-2,但名字让我感到困惑。

从 Windows 2000 开始,它们中的大多数都支持 UTF-16。在现代 Unicode 标准统一术语之前,选择了名称“wide”和其他 Microsoft 术语(例如,“Unicode”表示“UTF-16”或“UCS”)。

在 WideCharToMultiByte 中,Microsoft 使用“宽字符串”一词来表示 UTF-16。在这种情况下,什么被认为是“多字节字符串”?UTF-8?

在这种情况下,所有其他WideCharToMultiByte支持的编码都是“多字节编码”,包括 Windows-1251 和 UTF-8。

LPWSTR 是“宽字符串”吗?我会说它是,但是,那不是意味着它是 UTF-16 吗?这是否意味着它可以用来显示,比如说,4 字节字符?如果不是,那么...显示 4 字节字符是不可能的吗?(Windows 似乎没有这些 API。)

LPWSTR是一个指针,wchar_t在 Windows 上它始终是一个 16 位无符号整数。可以显示哪些字符与编码无关,只要该编码可以编码所有 Unicode 字符即可。Windows 通常能够显示非 BMP 字符,但不能在任何地方显示(例如,控制台不能)。

WideCharToMultiByte 的功能是否是 wcstombs 的超集,它们是否都适用于相同类型的字符串?或者说,一个在 UTF-16 上工作,而另一个在 UCS-2 上工作?

真的不知道,但我不认为他们有太大的不同。我想您只是尝试将一些非 BMP 字符转换为 UTF-8 并查看结果是否正确。

文件路径是 UTF-16 还是 UCS-2?我知道 Windows 将其视为 Microsoft 文档中的“不透明字符数组”,但根据 fwprintf 等函数的 C 标准,是否有任何标准化编码?

文件路径确实是 UTF-16 字符的不透明数组,这意味着 Windows 在存储或读取文件名时不会执行任何类型的转换(如 Linux,与 Mac OS X 不同)。但是 Windows 仍然有其奇怪的大多数未定义的不区分大小写的行为,这会导致很多麻烦,因为被视为等效的文件名不一定相等。这打破了许多不变量;例如,在不受其他线程干扰的 Linux 上,如果您在某个目录中成功创建了两个文件Aa您最终会得到两个不同的文件,而在 Windows 上,您只会得到一个文件(通常,文件数量不可预测)。

什么是“ANSI”编码?这甚至是一个正确的术语吗?它与 ASCII 有什么关系?

ANSI 是美国标准化组织。在提到编码时使用这个词是用词不当,但经常使用,因此您应该注意它。我更喜欢术语legacy 8-bit encoding,因为我认为它本质上就是这样:一种非 Unicode 编码,仅为了与传统 (Windows 9x) 应用程序兼容而保留。在西方系统上,这通常是 Windows-1252,它是 ASCII 的正确超集。

于 2011-01-06T12:22:03.647 回答
8
  1. *A 函数使用了活动的 ANSI 代码页。

  2. *W 函数使用 UTF-16。

  3. 多字节是指在 CodePage 参数中传递的任何内容。它最常见的是活动的 ANSI 代码页或 UTF-8。

  4. LPWSTR 是一个 UTF-16 字符串,它可能会或可能不会以 null 结尾(请参阅MSDN

  5. 我对 wcstombs 一无所知,我总是使用 WideCharToMultiByte。

  6. 文件路径采用 UTF-16 格式。事实上,Windows 内部的所有文本都是 UTF-16。

  7. 对于 ANSI 编码,您需要详细阅读。您可能比从Wikipedia开始并从那里访问链接更糟糕。

我希望这会有所帮助,如果我有任何错误,任何了解更多的人请编辑此内容以更正任何错误!

于 2011-01-04T12:00:36.710 回答
7

宽字符串曾经是 UCS-2。从 Windows 2000 开始,宽字符串是 UTF-16。很高兴知道您是否需要维护一些旧的遗留系统。

于 2011-01-06T12:36:47.943 回答
2

首先,您会在这个 SO 主题中找到大量信息。

ASCII 是一个字符集,而不是编码。现在,有许多 8 位字符集,其中一个在系统中被设置为默认值(您可以在区域设置中更改它)。*A 函数接受该字符集中的 8 位字符。UTF-8 不是字符集,而是 Unicode 字符集的编码。*W 函数,据我所知,使用 UTF-16 而不是 UCS-2。

于 2011-01-04T10:10:23.357 回答