我一直在Windows中使用“unicodestring”,只要…我已经了解了Unicode(例如gradle后)。 但是,Win32API非常松散地提到“unicode”,这一直令我感到困惑。 特别是,MSN提到的“unicode”变体是UTF-16(尽pipe“wide char”术语来自于它曾经是UCS-2,而不是Unicode)。 但是,几乎没有提到Unicode规范化。
MSN有几页关于Unicode和Unicode规范化forms和函数来改变规范化forms 。 规范化的页面甚至说:
Win32和.NET Framework支持所有四种规范化forms。
但是,我没有在文档中的任何地方findWin32 API使用(或理解)的规范化forms。
问题1 :默认情况下用户input(如Edit控件)使用什么规范化表单,并通过MultiByteToWideChar()
转换?
问题2 :传递给Win32API函数的string必须是特定的规范化forms,还是内核和文件系统规范化不可知?
从MSDN文章使用Unicode规范化来表示字符串 。
Windows,Microsoft应用程序和.NET Framework通常使用常规输入方法以C格式生成字符。 对于Windows上的大多数用途,格式C是首选格式。 例如,窗体C中的字符是由Windows键盘输入产生的。 但是,从Web和其他平台导入的字符可以将其他规范化形式引入到数据流中。
更新:我已经包含了一些与问题#2相关的具体细节。
关于文件系统,标准化不是必需的 – 基于命名文件,路径和命名空间 。
对于由Windows文件I / O API函数使用的路径和文件名字符串,不需要执行任何Unicode规范化,因为文件系统将路径和文件名视为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中都相同。
用户输入默认使用什么规范化表单
取决于你的键盘布局/ IME。 如果你愿意的话,可以生成正常的C,D或者两者的混合物。
键盘布局倾向于NFC,因为在Unicode之前的日子里,他们通常在每个按键的本地代码页中输出一个单字节字符。 但是也有例外。
例如,使用Windows越南语键盘布局,一些变音符被键入为与字母组合的单个按键(例如,旋转音符â
),一些则被键入为变音符号(例如坟墓à
)。 Graheme a-with-circumflex-and-grave将被键入为一个ầ
,然后是组合grave, ầ
,在越南语代码页1258中将是0xE2,0xCC,并且将出现为U + 00E2,U + 0300在Unicode中。
这不是正常形式C(这将是ầ
+ 1EA7拉丁文小写字母A带有旋律和坟墓)也不是D(这将是U + 0061,U + 0302,U + 0300)。
在Windows世界和网络中,通常有NFC的文化偏好,在苹果世界中也有NFD的文化偏好。 但这并不是严格执行的,你应该期待应付混合和分解字符的混合。
内核和文件系统规范化不可知论?
是的,内核和文件系统对标准化并不知晓,而且很高兴地让你在同一个文件夹中有文件名ầ.txt
, ầ.txt
和ầ.txt
。
首先,谢谢你的一个很好的问题。 我在Michael Kaplan的博客中找到了答案:
但是由于Windows上的所有文本输入方法都倾向于使用相同的规范化形式(形式C),…