在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编码的字符串。 但是他们只能把它们看作char
, char16_t
或char32_t
序列; 他们不能把它们想象成一系列用特定机制编码的Unicode码点。 basic_string::length()
将返回代码单元的数量,而不是代码点。 显然,C标准库字符串函数是完全没用的
但是应该指出的是,Unicode字符串的“长度”并不意味着代码点的数量。 一些代码点正在组合“字符”(一个不幸的名字),它与以前的代码点相结合。 所以多个代码点可以映射到一个可视化的字符。
Iostreams实际上可以读/写Unicode编码的值。 为此,您将不得不使用语言环境来指定编码,并将其适当地插入到各个位置。 这说起来容易做起来难,我没有任何代码来告诉你如何。