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


84

提出一个相关问题之后,我想问一下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

和字符串文字:

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)

现在的问题是:是\x/ \u/\U字符引用的所有字符串类型自由组合?是否所有的字符串类型的固定宽度,即正是数组包含尽可能多的元素出现在文字,或\x/ \u/\U引用得到扩展成字节数量可变的?DOu""u8""串具有编码的语义,比如我可以说char16_t x[] = u"\U0010FFFF",与非BMP代码点被编码成两部分的UTF16序列?和类似的u8?在(1)中,我可以用写代孕\u吗?最后,是否有任何编码的字符串函数可以识别(即它们可以识别字符并可以检测到无效的字节序列)?

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


4
GCC确实编码u"\U0010FFFF"为代理对。
kennytm 2011年

Answers:


56

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

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

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

并非以您的意思。\x\u\U会根据字符串编码进行转换。这些“代码单位”(使用Unicode术语。Achar16_t是UTF-16代码单位)的数量取决于所包含字符串的编码。文字u8"\u1024"将创建一个包含2 chars和一个空终止符的字符串。文字u"\u1024"将创建一个包含1char16_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编码的字符串。但是,他们只能把它们当作序列charchar16_tchar32_t; 他们无法将它们视为使用特定机制编码的Unicode代码点序列。basic_string::length()将返回代码单位数,而不是代码点数。显然,C标准库字符串函数完全没有用

但是,应注意,Unicode字符串的“长度”并不表示代码点的数量。某些代码点正在组合“字符”(一个不幸的名称),该字符与先前的代码点相结合。因此,多个代码点可以映射到单个视觉字符。

实际上,Iostream可以读取/写入Unicode编码的值。为此,您将必须使用语言环境来指定编码并将其正确地注入到各个地方。这说起来容易做起来难,而且我身上没有任何代码可以告诉你如何做。


7
@Philipp:不,不是。Unicode专门为UTF-16代理保留它们。而且,如前所述,C ++ 0x的规范指出,如果尝试在该范围内指定代码点,编译将失败。
Nicol Bolas

12
您的链接证明它们代码点。如果您不信任维基百科,请阅读本标准第3章中的定义9和10。但是,在C ++ 0x中,规则§2.4 / 2禁止在字符串文字中使用代理代码点。
菲利普

1
阅读后,我也确认在字符串文字中接受了代理代码点。
George Kourtis 2014年

在C11,\x可以与任何使用不,例如U + 1F984不会与\ X前缀的工作,\u\U不能与ASCII控制字符使用,至少在锵。
MarcusJ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.