【发布时间】:2018-09-01 20:20:23
【问题描述】:
Windows 文档反复提及 UNICODE 和 UTF-16。我知道这是file system 的谎言(即它接受wchar_t 的任何序列)和other documentation 表明无效的UTF-16 只是“未定义”。所以我很困惑。我可以假设非文件系统API 会返回有效的 UTF-16?或者我应该假设它不会?
编辑:由于它会引起一些混乱,我将解释一些术语
UTF-16
UTF-16 在Unicode specification (pdf) 中定义。 FAQ 明确了什么是格式正确的 UTF-16,什么不是格式正确的 UTF-16:
是否存在无效的 16 位值?
未配对的代理在 UTF 中无效。这些包括 D80016 到 DBFF16 范围内的任何值,后跟 DC0016 到 DFFF16,或 DC0016 到 DFFF16 范围内的任何值,前面没有 D80016 到 DBFF16.
非字符呢?它们无效吗?
一点也不。非字符在 UTF 中有效,必须正确转换。有关非字符的定义和使用以及它们在每个 UTF 中的正确表示的更多详细信息,请参阅Noncharacters FAQ。
所以唯一的限制是前导代理必须后跟一个尾随代理(也称为代理对)。所有其他 wchar_t(16 位)值都应按原样接受。
UCS-2
正如 Ben Voigt 的回答中提到的那样。这是一个现在已经过时的编码,它允许任何 wchar_t 值。由于它没有与 UTF-16 相同的限制,UCS-2 字符串的子集是无效的 UTF-16。
【问题讨论】:
-
“非文件系统 API”,你的意思是 地球上的所有其他 API 吗?我在想这个问题可能有点太宽泛了。
-
@LasseVågsætherKarlsen 每个其他 Windows
WAPI。是的。 -
另外,我们在这里谈论什么样的验证?每个代码点都是有效且已知的代码点?这不会向前兼容,因为新的代码点会定期添加,看看最近几年添加的表情符号,比如 ????这是 2015 年添加的。
-
有效的 UTF-16 包含尚未定义的代码点。所以有效的 UTF-16 是任何 16 位整数的序列,除了尾随代理必须跟在前导代理之后,反之亦然。
-
@las:
WideCharToMultiByte将不可避免地需要进行 UTF-16 验证。这个问题讨论了文件系统 API,因为底层文件系统(主要是 NTFS)并不关心 UTF-16。它会很乐意使用任何非零的 16 位数字序列来命名文件。