这个网站上有很多关于 Unicode 和
wchar_t
的问题。我想我已经掌握了这个概念,但后来发现了一些东西,证明如果它是真的,大多数(如果不是全部)答案都是错误的。在此页面上,微软声称onewchar_t
字符可以容纳anyUnicode字符(强调我的):
宽字符是 2 字节的多语言字符代码。全球现代计算中使用的任何字符,包括技术符号和特殊出版字符,都可以根据 Unicode 规范表示为宽字符。 由包括 Microsoft 在内的大型联盟开发和维护,Unicode 标准现已广泛使用已接受。
宽字符的类型为 wchar_t。宽字符字符串表示为 wchar_t[] 数组。您使用 wchar_t* 指针指向数组。
由于这个声明是直接来自微软的,所以我现在很担心:
“两字节多语言字符代码”如何容纳已包含大约 150,000 个代码点(字符)的 Unicode 字符集的任何字符? [ 另外,如果算上私人使用的码点、代理、已经预留的码点等等,会超过 1,000,000 个码点吗? ]
我希望这个问题不是重复的,因为它的核心是微软本身声明了一些似乎完全错误的东西,我真的很想知道我误解了什么特别是在我链接的微软页面上。
顺便说一句,还有Windows 使用 UTF-16 编码来表示 Unicode 字符,其中每个字符被编码为一个或两个 16 位值。很明显,我们有时需要
two wchar_t
字符(4 个字节)来表示 Unicode 代码点。好吧,这在某种程度上是有道理的,但考虑到相互矛盾的文档,我现在完全不确定。如果有人对这个问题的起源感兴趣:
在我的一个项目中,我有一个字符串,其中某个固定位置的字符必须被另一个字符替换。这会循环发生,并且必须尽快完成。这对于普通的
char[]
弦来说是理所当然的。但有问题的字符串是
wchar_t[]
类型,并且我无法控制替换字符。根据上述 Microsoft 陈述中哪一个是正确的,这也是理所当然的(如果第一个陈述为真),但如果第二个陈述为真,那就会变得一团糟:我不能只是替换替换字符对应索引处的
wchar_t
字符,因为原始字符可能是一个
wchar_t
,而第二个字符可能需要两个
wchar_t
,反之亦然。这就是为什么我想知道哪些文档是真实的。
据我推测,微软当时使用的 Unicode 编码是 UCS-2(即 AFAIU、UTF-16,但没有代理对,换句话说,仅限于基本多语言平面的 65,536 个字符)。
在这种情况下,以及对 Unicode 所涵盖内容的适当狭窄(Unicode 2.0 之前)的看法,该文档是正确的。
所以,现在 Windows API 是 UTF-16,这种编码是多字节的,因此每个代码点可能有 1 或 2 个 wchar。所以你不能像你指出的那样只用索引替换,因此,最好相信你的问题中的第二个链接。
但是,历史上 UTF-16 源于现已过时的 UCS-2 编码,它是 2 字节固定宽度,每个代码点始终是单个 wchar。该编码在某个时间点(大约在 2000 年之前)被命名为“Unicode”,这就是为什么第一个链接在撰写本文时是正确的,但现在不再正确了。
https://web.archive.org/web/20030818043641/http://www.unicode.org/faq/basic_q.html#23