【问题标题】:Unicode - generally working with it in C++Unicode - 通常在 C++ 中使用它
【发布时间】:2010-02-24 17:15:08
【问题描述】:

假设我们有一个任意字符串,s

s 具有来自世界任何地方的属性。来自美国、日本、韩国、俄罗斯、中国和希腊的人们都会时不时地写到s。不过,幸运的是,我们没有使用线性 A 的时间旅行者。

为了讨论,假设我们想要进行字符串操作,例如:

  • 反向
  • 长度
  • 大写
  • 小写
  • 索引到

,只是因为这是为了讨论,假设我们想自己编写这些例程(而不是抓取一个库),我们没有要维护的遗留软件。

Unicode 有 3 个标准:utf-8、utf-16 和 utf-32,各有优缺点。但是假设我有点笨,我想要一个 Unicode 来统治所有这些(因为为 3 种不同类型的字符串编码滚动一个动态适应库来隐藏 API 用户的差异听起来很难)。

  • 哪种编码最通用?
  • wchar_t 支持哪种编码?
  • STL 支持哪种编码?
  • 这些编码是否全部(或根本不)以空值结尾?

--

这个问题的重点是教育我自己和其他人了解有关 Unicode 的有用和可用信息:阅读 RFC 很好,但是有一堆与编译器、语言和操作系统相关的信息,而 RFC 没有封面,但对于在实际应用中实际使用 Unicode 至关重要。

【问题讨论】:

  • 不完全是骗子,但也读了stackoverflow.com/questions/114611/…
  • @Martin:我对什么是最好的图书馆并不感兴趣。我更感兴趣的是让自己快速了解有关 Unicode 的一般信息,以及我将如何使用 Unicode 编写反向(或者可能是更晦涩的例程)而不让它在土耳其等地爆炸。 :-)
  • 是的,这就是为什么我没有像骗子一样关闭,但是发现这个问题的人可能对使用库感兴趣。如果这个帖子得到了很好的答案,我会在另一个帖子中交叉引用它。

标签: c++ unicode


【解决方案1】:
  1. 哪种编码最通用
    可能是 UTF-32,尽管这三种格式都可以存储任何字符。 UTF-32 具有每个字符都可以在单个代码点中编码的特性。

  2. wchar_t 支持哪种编码
    没有任何。那是定义的实现。在大多数 Windows 平台上是 UTF-16,在大多数 Unix 平台上是 UTF-32。

  3. STL 支持哪种编码
    没有真的。 STL 可以存储您想要的任何类型的字符。只需使用 std::basic_string<t> 模板,其类型足以容纳您的代码点。大多数操作(例如std::reverse)不知道任何类型的 unicode 编码。

  4. 这些编码是否全部(或根本不)以空值结尾?
    不,Null 在任何这些编码中都是合法值。从技术上讲,NULL 也是纯 ASCII 中的合法字符。 NULL 终止是 C 的东西——不是编码的东西。

选择如何执行此操作与您的平台有很大关系。如果您在 Windows 上,请使用 UTF-16 和 wchar_t 字符串,因为这是 Windows API 用于支持 unicode 的内容。我不完全确定 UNIX 平台的最佳选择是什么,但我知道它们中的大多数都使用 UTF-8。

【讨论】:

  • 即使使用 UTF-32,您也无法将每个字符存储为单个代码点。该编码只是确保代码单元和代码点之间的 1:1 映射(有关术语的详细信息,请查看 unicode.org)
  • Err.. 实际上,它可以。 Unicode 需要 21 位来表示完整的字符集。 UTF-32 在单个代码点中提供 32 位。永远不需要在 UTF-32 上拆分字符。您正在考虑使用 UTF-16。
  • 您在这里谈论的是代码点,而不是字符。无论编码如何,一些(实际上很多)字符都需要用多个代码点来描述。看看这个链接,例如:unicode.org/faq/char_combmark.html
  • 哦——我明白你现在在说什么了。不过,unicode.org 上encoded character 上的文档并没有使这一点变得显而易见。
  • 关于组合字符的好点。 “a umlaut o”等于“äo”,应倒转为“oä”。将其反转为“o umlaut a”会产生“öa” - 注意变音符号的跳跃。
【解决方案2】:

查看开源库ICU,尤其是Docs & Papers section。这是一个处理各种 unicode 怪异的庞大库。

【讨论】:

  • OP 明确要求提供非图书馆答案。
  • 这就是我提到他们的文档和论文部分的原因。如果 OP 真的想了解 unicode 处理,他不应该避免查看现有的解决方案。 ICU不仅提供生产级源代码,还提供设计文档。
【解决方案3】:

作为对您最后一个要点的回应,UTF-8 保证在其任何字符的编码中都没有 NULL 字节(当然,NULL 本身除外)。因此,许多处理以 NULL 结尾的字符串的函数也可以处理 UTF-8 编码的字符串。

【讨论】:

    【解决方案4】:

    定义“真实应用”:)

    说真的,这个决定很大程度上取决于您正在开发的软件类型。如果您的目标平台是 Win32 API(带有或不带有 MFC、WTL 等包装器),您可能希望将 wstring 类型与编码为 UTF-16 的文本一起使用。这仅仅是因为所有 Win32 API 在内部都使用该编码。

    另一方面,如果您的输出类似于 XML/HTML 和/或需要通过 Internet 传递,则 UTF-8 几乎是标准 - 它通常通过假设字符具有 8 个的协议很好地传输位。

    至于 UTF-32,我想不出使用它的单一理由,除非您需要代码单元和代码点之间的 1:1 映射(这仍然不意味着代码单元和字符之间的 1:1 映射!)。

    有关详细信息,请务必查看 Unicode.org。 This FAQ 可能是一个很好的起点。

    【讨论】:

    • 我不清楚的一点是:任何 UTF 编码都可以代表当今所有生活语言著作中使用的所有字形吗?也就是说,如果我选择 UTF-8 或 UTF-16,我是否会将自己锁定在某些市场之外?
    • @保罗。 UTF-8、UTF-16 和 UTF-32 描述完全相同的数据(Unicode 代码点),只是编码不同,从严格的技术上讲,您可以使用它们中的任何一个来存储 Unicode 标准涵盖的任何文本(涵盖所有现存语言) .话虽如此,您需要考虑非技术问题:例如,即使标准 Unicode 编码形式也涵盖中文字母,中国也强制使用 GB18030。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    • 2016-01-04
    • 2023-03-29
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多