【问题标题】:Working with UTF-8 vs UTF-16 vs UTF-32 internally within C++?在 C++ 内部使用 UTF-8、UTF-16 和 UTF-32?
【发布时间】: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 字符串,那将非常有帮助。

标签: c++ unicode utf-8


【解决方案1】:

我碰到了我很老的答案,我会告诉你我最终做了什么。我决定坚持使用 UTF-8将我的数据存储在 std::string 或单字节字符数组中。我从来不需要使用多字节字符!

我使用的第一个库是 UTF8-CPP,它很容易引入您的应用程序和使用。但是你很快就会发现你需要越来越多的能力。

我真的很想避免使用 ICU,因为它是一个非常大的库,但是一旦你构建并安装它,你就会开始希望你一开始就完成了它,因为它拥有你需要的一切,而且很多,更多。

您可能想知道我的好处是什么:

  • 我编写了真正可移植的代码,这些代码在 Windows 的 VC++ 或 Linux 的 GCC 下构建。
  • ICU 拥有一切,我的意思是您需要的关于 unicode 的一切。
  • 我能够坚持使用我心爱的 std::string 和 char 数组。
  • 我在我的应用程序中使用了许多开源库,并且零问题。例如,我对我的 JSON 使用 RapidJson 来创建包含 UTF-8 数据的内存中 JSON 对象。我可以将它们传递到网络服务器或将它们写入磁盘等。真的很简单。
  • 我将数据存储到 Firebird SQL,但您需要将 varchar 和 char 字段类型指定为 UTF8。这意味着您的字符串将作为多字节存储在数据库中。但这对开发人员来说是完全透明的。我确信这也适用于其他 SQL 数据库。

缺点:

  • 大型图书馆,一开始非常可怕和混乱。
  • C++ 不是由 C++ 专家(如 Boost 开发人员)编写的。但是代码是完全稳定和快速的。您可能不喜欢使用的语法。我所做的是用我的代码“包装”通用过程。这几乎意味着我包含了我自己的 UTF-8 库,它包装了 ICU 丑陋的东西。不要让这困扰您,因为 ICU 完全稳定且快速。
  • 我个人将 ICU 动态链接到我的应用程序中。这意味着我首先为我的 Win 和 Linux 64 位环境动态构建了 ICU。对于 Windows,我将 dll 存储在某个文件夹中,并将其添加到我的 Windows 路径中,以便任何需要 ICU 的应用程序都可以找到这些 dll。

当我查看内置语言功能时,我发现一些不足之处,例如小写/大写转换、单词边界、字符计数、重音敏感度、字符串处理(如子字符串)等。本地支持也非常棒。

我想这总结了 UTF-8 中的整个练习。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 2011-02-10
    • 2014-08-21
    • 2012-08-18
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2010-09-12
    相关资源
    最近更新 更多