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

标签 c++ unicode c++11 utf string-literals

关注 related question ,想请教一下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""u8"" 字符串是否具有编码语义,例如我可以说 char16_t x[] = u"\U0010FFFF",然后将非 BMP 代码点编码为两个单元的 UTF16 序列吗? u8 也是如此?在 (1) 中,我可以用 \u 编写单独的代理吗?最后,是否有任何字符串函数编码感知(即它们是字符感知并且可以检测无效字节序列)?

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

最佳答案

Are the \x/\u/\U character references freely combinable with all string types?

没有。 \x 可以用在任何地方,但 \u\U 只能用在专门 UTF 编码的字符串中。但是,对于任何 UTF 编码的字符串,\u\U 可以根据需要使用。

Are all the string types fixed-width, i.e. the arrays contain precisely as many elements as appear in the literal, or to \x/\u/\U references get expanded into a variable number of bytes?

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

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

Do u"" and u8"" strings have encoding semantics, e.g. can I say char16_t x[] = u"\U0010FFFF", and the non-BMP codepoint gets encoded into a two-unit UTF16 sequence?

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

In (1), can I write lone surrogates with \u?

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

Finally, are any of the string functions encoding aware (i.e. they are character-aware and can detect invalid byte sequences)?

绝对不是。好吧,请允许我改写一下。

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

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

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

关于c++ - C++11 中字符串文字的 Unicode 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6796157/

相关文章:

python - 当我尝试删除 Python 字符串中的重音符号时,如何修复出现的 UnicodeDecodeError?

mysql - unicode 字符串 : difference between Habo and Håbo

haskell - 在 Haskell 中查找字符的 Unicode 脚本

c++ - std::unordered_map:渐近 {search,insert,remove} 在键的大小和数据类型方面的表现

c++ - do-while循环,无限循环

c++ - 如何添加那些自己包装 block 的代码包装器?

c++ - 在 lambda 表达式中指定捕获的变量的目的是什么?

c++ - 如何使用另一个类作为类模板特化

c++ - OpenGL 使用单个 VBO 渲染多个对象,使用另一个 VBO 更新对象的矩阵

c++ - 在C++中动态创建指针函数