【问题标题】:Using narrow string manipulation functions on wide data对宽数据使用窄字符串操作函数
【发布时间】:2011-06-02 18:03:11
【问题描述】:

我正在解析一个 XML 文件,该文件可以包含不同语言的本地化字符串(目前它只有英语和西班牙语,但将来可能是任何语言),XML 解析器的 API 返回XML 通过 UTF8 编码的 char*。

在解析数据后需要对数据进行一些操作(在其中搜索子字符串、连接字符串、确定子字符串的长度等)。

使用 strlen、strcat 等标准函数会很方便。由于我从 XML 解析器接收的原始数据是 char*,因此我可以使用这些标准字符串处理函数轻松完成所有操作。

然而,所有这些当然都假设和要求字符串是 NULL 终止的。 因此,我的问题是 - 如果您有表示为 char* 的宽数据,NULL 终止符是否会出现在数据中而不是末尾?

即如果某种语言中的一个字符不需要 2 个字节来表示它,并且它用一个字节表示,那么另一个字节是否会/可以为 NULL?

【问题讨论】:

    标签: c utf-8 internationalization widestring


    【解决方案1】:

    UTF-8 不是“宽”的。 UTF-8 是多字节编码,其中 Unicode 字符可以占用 1 到 4 个字节。 UTF-8 在有效字符内不会有零终止符。确保您对解析器提供给您的内容不感到困惑。它可以是 UTF-16 或 UCS2 或它们的 4 字节等价物放置在宽字符串中,在这种情况下,您必须将它们视为宽字符串。

    【讨论】:

    • 因此,如果解析器返回 UTF8,我可以将 UTF-8 数据作为 char* 进行操作,然后在显示字符串之前调用 UTF8toUTF16 转换函数? (gui 元素采用 uint16*(unsigned short) 参数)。
    • 是的,但是当字符串以 UTF-8 编码时,您不会知道字符串中有多少个字符。
    • @cababunga:BMP(最多 0xFFFF)被 3 个字节覆盖,所有 UTF-16 可表示代码点(最多 0x10FFFF)被 4 个字节(最多 0x1FFFFF)覆盖。 Unicode 已声明它们不会使用大于 0x10FFFF 的代码点,并且 Unicode UTF-8 最多为 4 个字节。我相信 ISO-10646 UTF-8 仍然最多 6 个字节,最多覆盖 0x7FFFFFFF(即 31 位)。
    • 我很确定 ISO-10646 也被修改来解决这个问题(删除无用的 5 和 6 字节序列)。无论如何,IETF RFC 也禁止它们。
    • @cababunga:更重要的是,非ASCII字符的表示上不会出现ASCII字符。
    【解决方案2】:

    C 区分多字节字符宽字符

    • 宽字符必须能够使用完全相同的字节数来表示执行字符集中的任何字符(例如,如果兀需要 4 个字节来表示,那么 A 也必须使用 4要表示的字节)。宽字符编码的示例包括 UCS-4 和已弃用的 UCS-2。

    • 多字节字符可以采用不同数量的字节来表示。多字节编码的例子有 UTF-8 和 UTF-16。

    使用 UTF-8 时,您可以继续使用 str* 函数,但您必须记住,它们不提供以 字符 为单位返回长度的方法字符串,需要转换成宽字符,使用wcslenstrlen 返回以 bytes 为单位的长度,而不是 characters,这在不同的情况下很有用。

    我怎么强调都不过分,执行字符集的所有元素都需要表示为一个预定义大小(以字节为单位)的单个宽字符。一些系统的宽字符使用UTF-16,结果是实现不符合C标准,一些wc*函数可能无法正常工作。

    【讨论】:

    • XML 解析器输出的内容类似于“text1 {.text2} {text3}”。我需要从中形成像“text1 somethingelse text3”这样的字符串。所以需要解析 '{', '}' 和 '.'并建立一个新的字符串。如果我处理'{','}','.'以外的内容作为字节流而不是字符,我假设我可以使用 strcpy、strcat 等函数来构建结果,然后将结果转换为 utf16。
    • 是的,正如我所说,str* 函数大多在 UTF-8 中工作,具有相同的语义,除了 strlen(),因为 char = byte, @987654329 @≠byte/char.
    猜你喜欢
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多