使用C++ 11,我还需要一个用于Unicode文本的非标准字符串操作库吗?

11 c++ unicode c++11

我注意到std :: string的length方法返回字节长度,std :: u16string中的相同方法返回2字节序列的数量.

我还注意到,当字符或代码点在BMP之外时,长度返回4而不是2.

此外,Unicode转义序列仅限于\ unnnn,因此转义序列不能插入U + FFFF上方的任何代码点.

换句话说,似乎不支持BMP之外的代理对或代码点.

鉴于此,使用理解UTF-8,UTF-16,代理对等的非标准字符串操作库是否被接受或推荐?

我的编译器是否有错误或我是否错误地使用标准字符串操作方法?

例:

/*
* Example with the Unicode code points U+0041, U+4061, U+10196 and U+10197
*/

#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
    std::string example1 = u8"A?";
    std::u16string example2 = u"A?";

    std::cout << "Escape Example: " << "\u0041\u4061\u10196\u10197" << "\n";
    std::cout << "Example: " << example1 << "\n";
    std::cout << "std::string Example length: " << example1.length() << "\n";
    std::cout << "std::u16string Example length: " << example2.length() << "\n";

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我用GCC 4.7编译时得到的结果:

Escape Example: A??6?7
Example: A?
std::string Example length: 12
std::u16string Example length: 6
Run Code Online (Sandbox Code Playgroud)

bam*_*s53 9

std::basic_string是面向代码单元,而不是面向字符.如果您需要处理代码点,您可以转换为char32_t,但标准中没有任何内容可用于更高级的Unicode功能.

\UNNNNNNNN除了直接输入非BMP代码点之外,您还可以使用转义序列(假设您正在使用支持它们的源代码编码).

根据您的需要,这可能是您需要的所有Unicode支持.许多软件不需要比字符串的基本操作更多,例如那些可以直接在代码单元上轻松完成的操作.对于稍高级别的需求,您可以将代码单元转换为代码点并对其进行处理.对于更高级别的需求,例如处理字形集群,将需要额外的支持.

我想说这意味着标准中有足够的支持来表示Unicode数据和执行基本操作.无论第三方库用于更高级别的功能,都应该建立在标准库上.随着时间的推移,标准也可能包含更多更高级别的功能.


jog*_*pan 7

由于过早判断的风险,在我看来标准中使用的语言略有模糊(虽然最终结论很清楚,最后见):

在char16_t文字的描述中(即u"..."您的示例中的文字),文字的大小定义为:

char16_t字符串文字的大小是转义序列,通用字符名称和其他字符的总数,加上需要代理项对的每个字符一个,加上一个用于终止u'\ 0'.

脚注进一步澄清:

[注意:char16_t字符串文字的大小是代码单元的数量,而不是字符数. - 尾注]

这意味着字符代码单元的定义.代理对是一个字符,但是两个代码单元.

但是,(由其衍生的)length()方法的描述声称:std::basic_stringstd::u16string

返回字符串中的字符数,即std :: distance(begin(),end()).它与size()相同.

如图所示,length()使用单词character的描述意味着char16_t调用代码单元的定义.

但是,所有这些结论是:长度被定义为代码单元,因此您的编译器符合标准,并且将继续需要特殊库来提供正确的字符计数.

我使用下面的参考:

  • 对于char16_t文字大小的定义:这里
  • 对于std::basic_string::length():这里的描述