【发布时间】:2014-09-07 17:48:47
【问题描述】:
我只有处理 ASCII(单字节字符)的经验,并且阅读了许多关于人们如何以不同方式处理 Unicode 的文章,这些文章提出了他们自己的一系列问题。
在我对 Unicode 的了解非常有限的时候,我了解到使用 UTF-16 进行内部处理会带来可移植性和其他问题。
我觉得 UTF-32 比 UTF-16 更有意义,因为所有 Unicode 字符都适合 4 个字节,但会消耗更多资源,特别是如果您主要处理 ISO-8859-1 字符.
我觉得 UTF-8 可能是内部使用的理想格式(尤其是在您主要处理基于英语和拉丁字符的情况下),因为将处理 ASCII 范围的字符逐字节非常有效。拉丁字母的字符会占用两个字节,当然其他字符会占用更多的字节。
我看到的另一个优点是 UTF-8 字符串可以存储在常规 C++ std::string 或 C 字符串数组中,这看起来很自然。
至少对我来说使用 UTF-8 的缺点是我没有找到任何内部支持 UTF-8 的库。例如,我还没有找到任何用于 UTF-8 大小写转换和子字符串操作的库。
对我来说另一个缺点是我还没有找到函数来解析 UTF-8 字符串中的字节以进行字符处理。
在内部使用 UTF-8 是否可行?是否有任何支持库可用于此目的?我希望如此,但如果不是,我认为我最好的选择是忘记在内部使用 UTF-8 并使用 Boost::Locale,因为我已经阅读了 ICU是许多人用来处理 Unicode 的成熟库。
我真的很想听听您对此事的意见。
【问题讨论】:
-
转换为大写/小写和子字符串相当容易(而且比通常认为的需要更少)。您通常会解析输入,然后将字符串作为原子值使用。例外情况很少见。如果您处于这些例外之一的领域,您可能需要 ICU。如果您不需要 ICU 的全部功能,您可能需要查看一些轻量级的 utf-8 库,例如 UTF8-CPP。
-
我将存储为不可变的 utf-8,并编写 utf-32 迭代器进行读取,并插入为 utf-32。对子字符串操作使用子字符串“视图”(可能带有对源的引用计数)。这提供了简单的字符访问和紧凑的存储空间。
-
@n.m.:“转换为大写/小写和子字符串相当容易”。怎么会这样?你肯定知道臭名昭著的德语“ß”,它在大写字母中变成了“SS”。因此,从大写到小写的正确德语转换需要几乎智能的自然语言解析,因为“BUSSE”可能会变成“Busse”或“Buße”,具体取决于实际意思是哪个词(以及您是在瑞士还是在德国或奥地利) .
-
我会同样习惯使用 UTF-16 或 UTF-8,但是,通过在内部使用 UTF-16,我节省了在运行时将每个字符串转换为另一种编码的开销,只是为了渲染它直接写入。
-
@n.m.对我来说,这似乎有点困难,因为 UTF-8 不是固定宽度,您不必检查 1 的高位,然后是 0 来确定字符消耗的字节数吗?如果您有一个代码 sn-p 显示如何为非 ASCII 字符设置大小写,甚至如何正确遍历 UTF-8 字符串,那将非常有帮助。