(编码)C ++中的字符串处理 - 问题/最佳实践?

时间:2009-01-11 20:26:37

标签: c++ string unicode

在C ++中处理字符串的最佳做法是什么?我特别想知道如何处理以下情况:

  • 文本和XML文件的文件输入/输出,可以用不同的编码编写。处理此问题的推荐方法是什么,以及如何检索值?我猜,XML节点可能包含UTF-16文本,然后我必须以某种方式使用它。

  • 如何处理char*字符串。毕竟,这可以是无符号或不符号,我想知道我如何确定他们使用的编码(ANSI?),以及如何转换为UTF-8?是否有任何推荐阅读,其中记录了关于字符串的C / C ++的基本保证?

  • UTF-8等字符串的字符串算法 - 计算长度,解析等。这样做最好?

  • 什么字符类型真正可移植?我已经知道wchar_t可以是8-32位宽的任何东西,如果我想在不同平台之间保持一致(特别是在不同平台之间移动数据时 - 这似乎是一个问题,因此它不是一个好的选择。例如在EASTL, look at item #13

  • 中描述

目前,我在任何地方使用std::string,在调用Unicode-API时使用小帮助器实用程序转换为UTF-16,但我很确定这不是最好的方法。使用类似Qt的QString或ICU String类似乎是正确的,但我想知道是否有更轻量级的方法(即我的char字符串是ANSI编码的,而ANSI的子集是used等于UFT-8,然后我可以很容易地将数据视为UTF-8并提供转换器来自/到UTF-8,我已经完成了,因为我可以将它存储在std::string中,除非有这种方法的问题)。

2 个答案:

答案 0 :(得分:3)

对于较短的答案,我建议使用UTF-16以简化;为简单起见,Java / C#/ Python 3.0切换到该模型。 我一直希望wchar_t为16或32bit宽,许多平台都支持它;实际上,像wcrtomb()这样的API不允许实现支持wchar_t *的移位状态,但由于UTF-8不需要,可以使用它,而排除其他编码。

然后,我回答有关XML的问题。

  

文本和XML文件的文件输入/输出,可以用不同的编码编写。处理此问题的推荐方法是什么,以及如何检索值?我猜,XML节点可能包含UTF-16文本,然后我必须以某种方式使用它。

我不确定,但我不这么认为。 在同一个文件中混合两个编码会导致问题和数据损坏。 以UTF-16编码文件通常是一个糟糕的选择,因为大多数程序都依赖于使用ASCII。 问题是:XML文件可能使用任何单一编码,甚至可能使用UTF-16,但是初始编码声明也必须使用UTF-16,甚至是标签。我在UTF-16中看到的问题是:如何可靠地解析初始声明?答案来自规范:,§4.3.3:

  

如果没有外部传输协议(例如HTTP或MIME)提供的信息,对于实体来说,这是一个致命错误,包括以不同于声明中指定的编码方式呈现给XML处理器的编码声明,或者对于既不以字节顺序标记也不以编码声明开头的实体来使用UTF-8以外的编码。请注意,由于ASCII是UTF-8的子集,因此普通的ASCII实体不需要严格的编码声明。

阅读时,请注意XML文件也是一个实体,称为文档实体;通常,实体是文档的存储单元。从整个规范来看,我会说每个实体只允许一个编码声明,并且在读取它们时我会将所有实体转换为UTF-16,以便于处理。

Webography:

答案 1 :(得分:1)

  

UTF-8等字符串的字符串算法 - 计算长度,解析等。如何做到最好?

mbrlen为您提供C字符串的长度。我不认为std :: string可以用于多字节字符串,你应该使用wstring作为宽字符串。

一般情况下,你应该在你的程序中使用UTF-16并且仅在I / O上使用UTF-8(我不太了解其他选项,但它们肯定更复杂且容易出错)。< / p>

  

如何处理char *字符串。毕竟,这可以是无符号或不符号,我想知道我如何确定他们使用的编码(ANSI?),以及如何转换为UTF-8?是否有任何推荐阅读,其中记录了关于字符串的C / C ++的基本保证?

基本上,您可以使用任何编码,并且您将碰巧使用运行系统的本机编码,只要它是8位编码即可。 C诞生于ASCII,并且语言环境处理是事后的想法。多年来,每个系统主要理解一种原生编码,比如ISO-8859-x,而来自其他编码的文件甚至可能是不可表示的。

因为对于UTF-8字符串,一个字节并不总是一个字符,我猜测最安全的选择是为它们使用多字节字符串。我使用的C手册描述了抽象的多字节字符串,没有关于这些问题的详细信息(特别是关于使用的编码)。对于C,请参阅mbrlen和mbrtowc等函数。在我的Linux系统上,注意到它们的行为取决于LC_CTYPE,这可能意味着本机类型的多字节字符串。从文档中可以推断出,它们的API也支持您可以从一个字节转换为两个字节并返回的编码。

  

如何处理char *字符串。毕竟,这可以是无符号的,

如果你依赖于char的签名,你做错了。只有使用char作为数字类型时,chars的签名才有意义,然后你应该总是使用unsigned或signed chars;事实上,你应该假装普通字符既没有签名也没有签名,而像a > 0这样的表达式(如果是一个字符)具有未定义的语义。但是,无论如何它会有用吗?