我一直在Windows中使用“unicode字符串”...我已经了解了Unicode(例如毕业后的)。然而,Win32API非常宽松地提到“unicode”总是让我感到困惑。特别是,MSN提到的“unicode”变体是UTF-16(尽管“宽字符”术语来自于它曾经是UCS-2,而不是Unicode)。但是,它几乎没有提到Unicode规范化。
MSN有几页关于Unicode和Unicode Normalization Forms以及change the normalization form的功能。规范化页面甚至说:
Win32和.NET Framework支持所有四种规范化形式。
但是,我没有在文档中的任何地方找到Win32 API使用(或理解)规范化表单。
问题1 :默认情况下,哪些规范化表单用于用户输入(例如编辑控件)和通过MultiByteToWideChar()
进行转换?
问题2 :传递给Win32API函数的字符串必须采用特定的规范化形式,还是内核和文件系统规范化无关?
答案 0 :(得分:11)
来自MSDN文章Using Unicode Normalization to Represent Strings。
Windows,Microsoft应用程序和.NET Framework通常使用常规输入方法生成表单C中的字符。对于Windows上的大多数用途,表单C是首选表单。例如,表单C中的字符由Windows键盘输入产生。但是,从Web和其他平台导入的字符可以将其他规范化表单引入数据流。
更新:我已经提供了与问题#2相关的一些具体细节。
关于文件系统,不需要规范化 - 基于文章Naming Files, Paths, and Namespaces。
不需要对路径和文件名字符串执行任何Unicode规范化以供Windows文件I / O API函数使用,因为文件系统将路径和文件名视为不透明的WCHAR序列。在对相关Windows文件I / O API函数进行任何调用之外,应记住应用程序所需的任何规范化。
关于SQL Server,不需要规范化 - nor is data normalized when saved in the database。也就是说,在比较字符串时,SQL Server 2000在索引中使用its own string normalization机制;但是我找不到具体的细节。 SQL Server 2005文章states the same。
SQL Server 7.0的一个重要变化是为字符串比较提供了独立于操作系统的模型,因此从Windows 95到Windows 2000的所有操作系统之间的排序将保持一致。此字符串比较代码基于Windows 2000用于其自身字符串规范化的相同代码,并且在所有计算机和所有版本的SQL Server中封装为相同。
答案 1 :(得分:9)
默认情况下,用户输入使用哪种规范化形式
取决于您的键盘布局/ IME。如果你愿意,可以生成正常形式的C,D或两者的疯狂混合。
键盘布局倾向于NFC,因为在Unicode之前的日子里,他们通常会在每个按键的本地代码页中输出单字节字符。但也有例外。
例如,使用Windows越南语键盘布局,一些变音符号被键入为单个按键与字母组合(例如,用于旋转â
),有些被键入为组合变音符号(例如,严重à
) 。将graheme a-with-circumflex-and-grave键入a-circumflex,然后组合-grave,ầ
,在越南语代码页1258中为0xE2,0xCC,并将显示为U + 00E2 ,Unicode中的U + 0300。
这不是正常形式C(可能是ầ
U + 1EA7拉丁文小写字母A带有旋律和坟墓)也不是D(可能是ầ
U + 0061,U + 0302 ,U + 0300)。
在Windows世界和网络上,以及在Apple世界中的NFD,通常存在对NFC的文化偏好。但它没有严格执行,你应该期望应对任何组合和分解字符的混合。
是内核和文件系统规范化无关的吗?
是的,内核和文件系统对规范化一无所知,并且很高兴地允许您在同一文件夹中包含名称为ầ.txt
,ầ.txt
和ầ.txt
的文件。
答案 2 :(得分:2)
首先,感谢一个很好的问题。我在Michael Kaplan's blog中找到了答案:
但由于Windows上所有文本输入方法都倾向于使用相同的规范化形式(表单C),...