Windows API:ANSI和宽字符串 - 是UTF8还是ASCII? UTF-16或UCS-2 LE?

时间:2011-01-04 09:45:47

标签: winapi unicode ascii widechar multibyte-functions

我不太喜欢编码,但这是我认为我知道的(虽然它可能是错的):

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

    现在,对于问题:

    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文档中的“不透明字符数组”,但根据fwprintf等函数的C标准,是否有任何标准化编码?
    7. 什么是“ANSI”编码?这甚至是一个正确的术语吗?它与ASCII有什么关系?
    8. (我有更多问题,但这已经足够了......无论如何我忘记了其中一些......)
    9. 这些是很多问题,所以任何关于所有这些连接的解释的链接(除了阅读Unicode标准,无论如何都不会对Windows API有帮助)也将非常感激。

      谢谢!

4 个答案:

答案 0 :(得分:27)

  

这些都是正确的吗?

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

  

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

它们采用当前“ANSI”/ MBCS / legacy编码编码的字节字符串(即,代码单位为字节的字符串,在Windows上始终为八位字节)。 “ANSI”是这些编码的历史术语,但不正确。对于Western 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是美国的标准化组织。在提到编码时使用这个词是用词不当,但是经常使用,所以你应该知道它。我更喜欢术语传统的8位编码,因为我认为它本质上是这样的:非Unicode编码只保留与传统(Windows 9x)应用程序的兼容性。在Western系统中,这通常是Windows-1252,它是ASCII的正确超集。

答案 1 :(得分:7)

  1. *函数使用活动的ANSI代码页。

  2. * W功能使用UTF-16。

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

  4. LPWSTR是一个UTF-16字符串,可能会也可能不会以空值终止(请参阅MSDN

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

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

  7. 对于ANSI编码,您需要详细阅读。你可以做的比从Wikipedia开始更糟糕,并按照那里的链接。

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

答案 2 :(得分:5)

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

答案 3 :(得分:1)

首先,您会在this SO topic中找到大量信息。

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