在C ++ 11中对字符串文字进行Unicode编码

在相关的问题之后 ,我想问一下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引用扩展为可变数量的字节? 你和u""字符串是否有编码的语义,例如我可以说char16_t x[] = u"\U0010FFFF" ,非BMP的编码点被编码成两个单位的UTF16序列? 和u8类似吗? 在(1)中,我可以写出单独的代理吗? 最后,是否有任何字符串函数编码感知(即他们是字符感知和可以检测无效的字节序列)?

这是一个开放式的问题,但我想尽可能地得到新的C ++ 11的新的UTF编码和类型设施的图片。

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

编号\x可用于任何内容,但\u\U只能在特定于UTF编码的字符串中使用。 但是,对于任何UTF编码的字符串, \u\U都可以按照您认为合适的方式使用。

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

不是你的意思。 \x\u\U根据字符串编码进行转换。 这些“代码单元”(使用Unicode术语, char16_t是UTF-16代码单元)的数量取决于包含字符串的编码。 文字u8"\u1024"会创建一个包含2个char和一个空终止符的字符串。 字面u"\u1024"会创建一个包含1个char16_t加上一个空终止符的字符串。

所用代码单元的数量基于Unicode编码。

你和你的字符串是否有编码的语义,例如我可以说char16_t x [] = u“\ U0010FFFF”,非BMP的编码点被编码成两个单位的UTF16序列?

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

在(1)中,我可以写出单独的代理吗?

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

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

绝对不。 那么,请允许我重述一下。

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

但是应该指出的是,Unicode字符串的“长度”并不意味着代码点的数量。 一些代码点正在组合“字符”(一个不幸的名字),它与以前的代码点相结合。 所以多个代码点可以映射到一个可视化的字符。

Iostreams实际上可以读/写Unicode编码的值。 为此,您将不得不使用语言环境来指定编码,并将其适当地插入到各个位置。 这说起来容易做起来难,我没有任何代码来告诉你如何。