C ++中的字符串和字符编码

时间:2010-10-16 20:12:34

标签: c++ string unicode utf-8 character-encoding

我在C ++中阅读了一些关于字符串和字符编码最佳实践的帖子,但我在寻找一种似乎相当简单和正确的通用方法时遇到了一些困难。我可以就以下问题征询意见吗?我倾向于使用UTF-8和UTF-32,并定义类似的东西:

typedef std::string string8;
typedef std::basic_string<uint32_t> string32;

string8类将用于UTF-8,并且具有单独的类型只是提醒编码。另一种方法是将string8作为std :: string的子类,并删除不适合UTF-8的方法。

当需要固定字符大小时,string32类将用于UTF-32。

UTF-8 CPP函数utf8 :: utf8to32()和utf8 :: utf32to8(),或者更简单的包装函数,将用于在两者之间进行转换。

3 个答案:

答案 0 :(得分:10)

如果你打算只是传递字符串并且从不检查它们,你可以使用普通的std::string虽然这是一个穷人的工作。

问题在于,大多数框架,甚至是标准,都在内存中愚蠢地(我认为)强制编码。我说愚蠢,因为编码应该只对接口有影响,而那些编码不适合内存中的数据操作。

此外,编码很容易(它是一个简单的转码CodePoint - >字节和反向),而主要的困难实际上是操纵数据。

对于8位或16位,您可能会在中间剪切字符,因为std::stringstd::wstring都不知道Unicode字符是什么。更糟糕的是,即使使用32位编码,也存在将字符与适用于它的变音符号分开的风险,这也是愚蠢的。

因此,就标准而言,C ++中Unicode的支持非常低。

如果您真的希望操纵Unicode字符串,则需要一个支持Unicode的容器。通常的方法是使用ICU库,尽管它的界面实际上是C-ish。但是,您将获得使用多种语言实际使用Unicode所需的一切。

答案 1 :(得分:1)

所描述的特征方法here可能会有所帮助。这是一种古老但有用的技术。

答案 2 :(得分:1)

没有指定必须为字符串,wstring等使用什么字符编码。常见的方法是在宽字符串中使用unicode。应使用哪些类型和编码取决于您的要求。

如果您只需要将数据从A传递给B,请选择带有UTF-8编码的std :: string(不要引入新类型,只需使用std :: string)。如果必须使用字符串(extract,concat,sort,...),请选择std :: wstring,并在Windows上编码UCS2 / UTF-16(仅限BMP),在Linux上编辑UCS4 / UTF-32。 好处是固定大小:每个字符的大小为2(对于UCS4为4),而带有UTF-8的std :: string返回错误的length()结果。

对于转换,您可以检查sizeof(std :: wstring :: value_type)== 2或4以选择UCS2或UCS4。我正在使用ICU库,但可能有简单的包装库。

不建议从std :: string派生,因为basic_string不是为(缺少虚拟成员等)而设计的。如果你真的真的需要你自己的类型,比如std :: basic_string&lt; my_char_type&gt;为此写一个自定义专业。

新的C ++ 0x标准定义了wstring_convert&lt;&gt;和wbuffer_convert&lt;&gt;使用std :: codecvt从窄字符集转换为宽字符集(例如UTF-8到UCS2)。 Visual Studio 2010已经实现了这个,afaik。

相关问题