【问题标题】:UTF8 processing in CC中的UTF8处理
【发布时间】:2012-06-12 11:26:41
【问题描述】:

我对 UTF8 有基本的了解:码位具有可变长度,因此“字符”可以是 8 位、16 位,甚至更长。

我想知道的是,C 语言中是否有一些示例代码、库等与 UTF8 字符串类似,例如 C 中的标准库。告诉字符串的长度等。

谢谢,

【问题讨论】:

  • 请记住,例如strlen() 在 utf-8 编码数据上效果很好,它为您提供了 uft-8 字符串的长度。但是,它不会为您提供该字符串中的 unicode 字符数。
  • @nos 这是错误的,在几个方面。当然,如果字符串中有 U+0000 个码位,strlen 根本不起作用,这是完全合法的。说它告诉字符串的“长度”是不诚实的。它没有。它只告诉您字节数,而不是您想要的代码点数。
  • @tchrist 请记住,我们在这里讨论的是 UTF-8 编码的字符串。在 C 代码中,UTF-8 字符串在您遇到空字节时结束。 UTF-8 字符串的长度可能是也可能不是您想要的。例如如果要将字符串复制到新缓冲区中,或者需要确定字符串是否适合有限长度的数据库字段,则确实需要字节数。
  • @tchrist strlen 也不适用于包含 ASCII 代码 NUL 的 ASCII 字符串。但是我们不会到处说它不适用于 ASCII 字符串,对吗?

标签: c unicode utf-8


【解决方案1】:

处理 Unicode 的最重要的库是 IBM's ICU

但如果您只需要确定 UTF-8 编码字符串中的代码点数,请计算值介于 \x01\x7F 之间或介于 \xC2\xFF 之间的字符数。

【讨论】:

  • \xC2\xF4,实际上 - Unicode 停止在 U+10FFFF。仅对连续字节进行折扣可能更容易,您可以通过单个操作来做到这一点:c & \xC0 != \x80
  • 当然,或者,假设字符已签名,C >= '\xC2'
  • 此外,Unicode 不仅仅是一个字符集。您还必须考虑诸如 canonical equivalence 之类的事情(您应该将包含例如 U+0178 的字符串视为与包含 U+0059 U+0308 的字符串相同,即使第一个是 2 个字节long in UTF-8 和第二个 3 个字节)。但这可能超出了这个问题的范围。
  • 代码单位* 一个代码点基本上是一个字符或字形(带有星号,但这是一般概念)
  • @Marcus 不。在 UTF-8 中,一个代码单元是一个 8 位字节。这就是整个问题!我们需要计算代码点而不是代码单元!不过,我不确定您所说的星号是什么意思。
【解决方案2】:

GNU 确实有一个名为 libunistring 的 Unicode 字符串库,但它处理任何事情的能力都不如 ICU 的。

例如,GNU 库甚至不允许您访问排序规则,这是所有字符串比较的基础。相比之下,ICU确实如此。 ICU 中没有出现 GNU 的另一件事是 Unicode 正则表达式。为此,您可能希望使用Phil Hazel’s excellent PCRE library for C,它可以使用 UTF-8 支持进行编译。

但是,GNU 库可能足以满足您的需要。我不太喜欢它的 API。很乱。如果你喜欢 C 编程,你可以试试Go programming language,它具有出色的 Unicode 支持。这是一种新语言,但小巧、干净且使用起来很有趣。

另一方面,主要的解释性语言——Perl、Python 和 Ruby——都对 Unicode 提供了不同的支持,比 C 语言更好。其中,Perl 的 Unicode 支持是最发达和最强大的.

记住:支持更多字符是不够的。没有它们的规则,你就没有 Unicode。最多,您可能拥有 ISO 10646:一个大型字符库,但没有规则。我的口头禅是“Unicode 不仅仅是更多的字符;更多的字符加上一大堆处理它们的规则。”

【讨论】:

    【解决方案3】:

    如果您对不分配内存并使用堆栈的库感兴趣,您可以尝试utf8rewind

    【讨论】:

    • 本页 404ed.
    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 2013-04-06
    • 1970-01-01
    • 2011-04-17
    • 2015-02-21
    • 2013-07-21
    • 2014-06-02
    相关资源
    最近更新 更多