C++ 11中字符串文字的Unicode编码

Ker*_* SB 76 c++ unicode utf string-literals c++11

在一个相关的问题之后,我想问一下C++ 11中的新字符和字符串文字类型.看来我们现在有四种字符和五种字符串文字.角色类型:

char     a =  '\x30';         // character, no semantics
wchar_t  b = L'\xFFEF';       // wide character, no semantics
char16_t c = u'\u00F6';       // 16-bit, assumed UTF16?
char32_t d = U'\U0010FFFF';   // 32-bit, assumed UCS-4
Run Code Online (Sandbox Code Playgroud)

和字符串文字:

char     A[] =  "Hello\x0A";         // byte string, "narrow encoding"
wchar_t  B[] = L"Hell\xF6\x0A";      // wide string, impl-def'd encoding
char16_t C[] = u"Hell\u00F6";        // (1)
char32_t D[] = U"Hell\U000000F6\U0010FFFF"; // (2)
auto     E[] = u8"\u00F6\U0010FFFF"; // (3)
Run Code Online (Sandbox Code Playgroud)

问题是:\x/ \u/ \U字符引用是否可以与所有字符串类型自由组合?是否所有字符串类型都是固定宽度的,即数组包含与文字中出现的元素一样多的元素,或者\x/ \u/ \U引用是否扩展为可变数量的字节?Do u""u8""字符串有编码语义,例如我可以说char16_t x[] = u"\U0010FFFF",非BMP代码点被编码成一个双单元的UTF16序列吗?同样的u8?在(1)中,我可以写单独的代理人\u吗?最后,是否有任何编码感知的字符串函数(即它们是字符感知的并且可以检测无效的字节序列)?

这是一个开放式的问题,但我想尽可能完整地了解新的C++ 11的UTF编码和类型设施.

Nic*_*las 51

\ x /\u /\U字符引用是否可以与所有字符串类型自由组合?

\x可以在任何可以使用,但\u\U只能在那些专门UTF编码字符串中使用.然而,对于任何UTF编码字符串,\u并且\U可以作为您认为合适的使用.

所有字符串类型都是固定宽度的,即数组包含与文字中出现的元素一样多的元素,或者\ x /\u /\U引用是否扩展为可变数量的字节?

不是你的意思.\x,, \u\U基于字符串编码进行转换.这些"代码单元"(使用Unicode术语.A char16_t是UTF-16代码单元)值的数量取决于包含字符串的编码.该文字u8"\u1024"将创建一个包含2 chars加上空终止符的字符串.该文字u"\u1024"将创建一个包含1 char16_t加上空终止符的字符串.

使用的代码单元数基于Unicode编码.

u""和u8""字符串是否具有编码语义,例如我可以说char16_t x [] = u"\ U0010FFFF",非BMP代码点被编码为两个单元的UTF16序列?

u""创建一个UTF-16编码的字符串.u8""创建一个UTF-8编码的字符串.它们将按照Unicode规范进行编码.

在(1)中,我可以用\ u编写单独的代理人吗?

绝对不.该规范明确禁止使用UTF-16代理对(0xD800-0xDFFF)作为\u或的代码点\U.

最后,是否有任何编码感知的字符串函数(即它们是字符感知的并且可以检测无效的字节序列)?

绝对不.好吧,请允许我重新说一下.

std::basic_string不处理Unicode编码.它们当然可以存储 UTF编码的字符串.但是,他们只能把它们当作序列char,char16_tchar32_t; 他们不能将它们视为使用特定机制编码的Unicode代码点序列.basic_string::length()将返回代码单元的数量,而不是代码点.显然,C标准库字符串函数完全没用

然而,应该注意,Unicode字符串的"长度"并不意味着代码点的数量.一些代码点组合了"字符"(一个不幸的名称),它与前一个代码点结合在一起.因此,多个代码点可以映射到单个视觉角色.

Iostream实际上可以读/写Unicode编码的值.为此,您必须使用区域设置来指定编码并将其适当地添加到各个位置.这说起来容易做起来难,而且我没有任何代码可以告诉你如何.

  • 您的链接证明他们*是*代码点.如果您不相信维基百科,请阅读标准第3章中的定义9和10.但是,规则§2.4/ 2中的C++ 0x中禁止使用字符串文字中的代理代码点. (12认同)
  • @Philipp:[不,他们不是.](http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates)Unicode专门为UTF-16代理人保留它们.并且,如上所述,C++ 0x的规范说如果您尝试在该范围内指定代码点,则编译将失败. (7认同)