Nic*_*ick -1 c++ utf-8 character-encoding
我最近看了Computerphile 的 Tom Scott 谈论 UTF-8,之后进行了一些研究,了解到 UTF-8 可用于对最多 6 个字节的字符进行编码,每个字节使用以下标头:
0xxx xxxx # 1 Byte character
110x xxxx # 2 Byte character
1110 xxxx # 3 Byte character
1111 0xxx # 4 Byte character
1111 10xx # 5 Byte character
1111 110x # 6 Byte character
Run Code Online (Sandbox Code Playgroud)
然后用它10xx xxxx来表示额外的字节(我知道RFC3629将其限制为最多 4 个字节)。
我的理解是否正确,这允许对 2,164,286 个不同的字符进行编码(忽略任何保留字符)?
0xxx xxxx # 7 bits => 128
110x xxxx # 5 bits + 6 bits = 11 bits => 2,048
1110 xxxx # 4 bits + 6*2 bits = 16 bits => 65,536
1111 0xxx # 3 bits + 6*3 bits = 21 bits => 2,097,152
# == 2,164,864
Run Code Online (Sandbox Code Playgroud)
理论上,我可以使用char数组来存储 UTF-8 编码的字符串,或者我可以使用固定长度编码(如 UTF-32)并使用任何 4 字节类型(例如对unsigned long每个 UTF-8 编码字符进行编码),但这会增加对于仅使用 1 或 2 个字节编码的 UTF-8 字符的文本,内存会显着增加。
我相信std::string允许存储UTF-8,这将导致size并length返回字节长度,但是如果UTF-8可以表示不同长度的字符,那么语言(我们将采用C++来限制这个问题的范围)如何编码这些字符内部(例如在std::string)?
UTF-8 字符串是遵循一些限制的字节序列(即 -schar或uint8_tC++ 中的字节序列)(因此并非每个字节序列都是有效的 UTF-8 字符串;如果您从外部获取某个字符串,该字符串声称它是是 UTF-8,您应该验证它)。
因此,您可以使用std::string-s 来表示 UTF-8 字符串(前提是您确定它们是有效的 UTF-8)。
您可以在它们之上使用一些 UTF-8 库(例如libunistring或Glib Unicode Manipulation)。
换句话说,UTF-8 可以看作是关于如何使用字符串(of -s)的约定char。
当然,请注意字节数(例如size() a std::string)不是UTF -8 字符数。并且您不能使用普通迭代器来迭代 UTF-8 字符(或其等效的 Unicode)。
您可能会发现更多支持 UTF-8 的 C++ 库(例如Gtkmm 中的Glibmm ustring -s)或其他表示 Unicode 字符串的库(例如Qt 中的QString -s)。
顺便说一句,UTF-8(和 Unicode)在屏幕或纸张上正确渲染非常复杂(因此您需要一些库来实现)。您可能在同一个字符串中混合了多种语言(英语、俄语、阿拉伯语、中文),其中一些语言正在改变方向。您可能有组合字符(重音等)。Unicode 相当复杂(我不知道其中大部分,因为我不知道大多数人类语言;我只能说和读英语、法语、俄语。我可以破译一些希腊字母。我只知道很少的希伯来语字母。而中文对我来说完全是陌生的)。
另请参阅http://utf8everywhere.org/和有关UTF-8和Unicode的维基页面。