Unicode地狱(在Windows上)

时间:2011-08-12 12:39:53

标签: c++ winapi utf-8 utf-16 ucs2

6 个答案:

答案 0 :(得分:7)

强烈偏好,您应该在读取数据时从UTF- *转换为UCS-4。您的所有处理都应在UCS-4上完成,然后(如有必要)在输出期间转换回UTF- *。

但仍然无法解决所有问题。有一组“组合变音符号”标记,这意味着即使使用UCS-4,string[N]也不一定对应于字符串的N th 字符。有规范形式的转换试图帮助解决这个问题,但是它们并不总能完成这项工作,所以如果它真的很关键(对于你的应用程序),你只需要遍历字符串,将它分成每个单元。表示一个完整的字符(基本字符+和组合变音符号),并将每个字符视为一个单元。

答案 1 :(得分:5)

  1. ICU是一个出色的Unicode字符串库。字符串处理的一般概念是将任何外部表单解析为内存,使得每个值都是完整的代码点,而不是UTF-16和UTF-8的某些部分。然后,在任何处理之后,在离开程序的路上,将字符串序列化为适当的转换格式。尽管基础很简单,但是尽量不要使用自己的Unicode库 - 例如整理,搜索和其他复杂的事情最好留给成熟的库。

  2. BMP以外的平面没有使用也没有定义,因为没有看到需要。当然,正如你所指出的那样,肯定有需要。

  3. 是的,这很常见,如上所述,这是最好的做事方式,因为它大大改善了几乎所有的字符串操作。

答案 2 :(得分:5)

我对此事的看法:

  • 对于外部接口(文件,命令行参数,环境变量,stdin / out),请使用UTF-8,因为这是 byte 流,并且设计了整个C和C ++语言通过字节流与环境接口。在大多数敏感的文件系统上,文件名也是(以null结尾的)字节字符串。

  • 对于简单的parroting,您可以使用char*等内部以及""字符串文字或新的u8"" UTF在内部保留UTF-8字符串-8文字。

  • 对于文本操作,请在内部将字符串转换为UTC-4 / UTF-32,并将其视为char32_t的数组。这是你能说出字符流的唯一理智的方式。

  • UTF-16是一个巨大的错误,应该被射击和避开。 See here(我在某处发表了评论),也许是herehere

答案 3 :(得分:5)

  1. ICU - International Components for Unicode。为了正确的分词和显示,Windows包含Uniscribe,非Windows使用FreeType(如果我错了,请更正我)。

  2. 是的,我这样做。但据我所知,当他们做出这个决定时,utf-32并不存在,他们认为65536个代码点“对每个人来说都足够了”。

  3. 不,不是。除了内存使用量增加四倍外,问题还比你想象的要糟糕得多。你不能只是“修改一个字符串”和“替换一些字符”:即使使用32位值,因为一个unicode字符不一定意味着一个书面字母或一个字形,你可以删除或替换其他东西,并希望什么也不希望休息。要正确使用文本,你必须使用像ICU这样的东西,所以我认为使用utf-8和utf-32没有太大区别。

答案 4 :(得分:4)

我不知道你对wcs功能不好的意思。为什么不呢?

  

当我们被迫使用16位不足的W函数时,你是不是感觉出了一个丑陋的错误。难道问题不应该在更早的阶段得到认可,并且让所有原始API函数都采用UTF-8字符串并包含适当的字符串操作例程吗?或者这已经成为可能了,我是非常错误的吗?

在编写Windows Unicode接口后,UTF-8开发得很好。如果他们添加了UTF-8版本,那么现在每个功能都有3个版本。我敢肯定,如果再次重新开始,他们就不会使用UTF-16--后见之明真的太棒了。

关于UTF-32,几乎没有任何软件在内部使用它。我不推荐它,特别是在没有任何支持的平台上。使用UTF-32只会为自己创造工作。

答案 5 :(得分:1)

没有什么可以阻止你创建一个简单的缓存来存储UTF编码的代码点的位置和字节长度,这样你就可以实际使用随机访问。你所谈论的所有旧C语言都不会有太多帮助。

我也不相信UTF-8'BOM'可用,因为它是废话并且可能被剥离 远离某些实现。