Windows中的Unicode规范化

And*_*ron 23 windows unicode normalization unicode-normalization

我一直在使用"Unicode字符串"在Windows中,只要是......我了解的Unicode(如毕业).然而,Win32API非常宽松地提到"unicode"总是让我感到困惑.特别是,MSN提到的"unicode"变体是UTF-16(尽管"宽字符"术语来自于它曾经是UCS-2,而不是Unicode).但是,它几乎没有提到Unicode规范化.

MSN有几页关于UnicodeUnicode规范化表单和函数来更改规范化表单.规范化页面甚至说:

Win32和.NET Framework支持所有四种规范化形式.

但是,我没有在文档中找到Win32 API使用(或理解)归一化形式的任何地方.

问题1:默认情况下,用户输入(例如编辑控件)和转换的标准化形式是什么MultiByteToWideChar()

问题2:传递给Win32API函数的字符串必须是特定的规范化形式,还是内核和文件系统规范化无关?

jve*_*zey 12

从MSDN文章使用Unicode规范化来表示字符串.

Windows,Microsoft应用程序和.NET Framework通常使用常规输入方法生成表单C中的字符.对于Windows上的大多数用途,表单C是首选表单.例如,表单C中的字符由Windows键盘输入产生.但是,从Web和其他平台导入的字符可以将其他规范化表单引入数据流.

更新:我已经包含了与问题#2相关的一些具体细节.

关于文件系统,不需要规范化 - 基于文章命名文件,路径和命名空间.

无需对路径和文件名字符串执行任何Unicode规范化以供Windows文件I/O API函数使用,因为文件系统将路径和文件名视为不透明的WCHAR序列.在对相关Windows文件I/O API函数进行任何调用之外,应记住应用程序所需的任何规范化.

对于SQL Server,不需要规范化 - 在数据库中保存时也不会对数据进行规范化.也就是说,在比较字符串时,SQL Server 2000 在索引中使用自己的字符串规范化机制; 但是我找不到具体的细节.SQL Server 2005文章也说明了这一点.

SQL Server 7.0的一个重要变化是提供了一个独立于操作系统的模型进行字符串比较,因此从Windows 95到Windows 2000的所有操作系统之间的排序将保持一致.此字符串比较代码基于Windows 2000用于其自身字符串规范化的相同代码,并且在所有计算机和所有版本的SQL Server中封装为相同.


bob*_*nce 9

用户输入默认使用什么规范化表单

取决于您的键盘布局/ IME.如果你愿意,可以生成正常形式的C,D或两者的疯狂混合.

键盘布局倾向于NFC,因为在Unicode之前的日子里,他们通常会在每个按键的本地代码页中输出单字节字符.但也有例外.

例如,使用Windows越南语键盘布局,一些变音符号被键入为单个按键与字母组合(例如,用于旋转â),而一些键入键入为组合变音符号(例如,严重a?).grachme a-with-circumflex-and-grave将被输入a-circumflex,然后â?是combination -grave,在越南语代码页1258中将为0xE2,0xCC,并且将显示为U + 00E2,U + 0300 in Unicode格式.

这不是正常形式C(这是?U + 1EA7拉丁文小写字母A有旋律和坟墓),也不是D(可以是a??U + 0061,U + 0302,U + 0300).

在Windows世界和网络上,以及在Apple世界中对于NFD,通常存在对NFC的文化偏好.但它没有严格执行,你应该期望应对任何组合和分解字符的混合.

内核和文件系统是否与规范化无关?

是的,内核和文件系统不知道什么正常化,并会很乐意让你有与名称的文件â?.txt,?.txta??.txt在同一个文件夹.

  • 也许"标准化 - 无知"将是一种更明确的方式:对Windows而言,它们只是一堆代码点.它试图做的唯一"聪明"的事情是对它们不区分大小写.这很棘手,因为在不同的Unicode版本中,折叠规则已经改变了! (2认同)
  • @André:不,确实,'聪明'不是.NFC和NFD字符串在字符串处理级别通常是不同的,特别是在NTFS文件系统中.所以,是的,让用户手动键入文件路径来匹配可能会很痛苦.但至少当你从文件系统中读回文件名时,你会以你输入的相同形式得到它...在OS X(HFS +/UFS)上并非如此,这会迫使一切都变成NFD,导致令人讨厌的互操作问题. (2认同)