首页 > 解决方案 > 如何正确声明 char8_t 为变音字母?

问题描述

标签: c++visual-c++utf-8utfc++20

解决方案


char8_t, char, signed char, 和unsigned char, 的大小为 1 字节。在大多数平台(但不是全部!)上,这意味着它是一种 8 位类型,只能保存 256 个离散值。Unicode 12.1 定义了 137,994 个字符。显然,它们不能都适合一个char8_t值!

遗憾的是,C 和 C++“字符”类型命名不当。如果我们使用现代术语设计一种新语言,我们会为它们命名一些变体,code_unit因为这样可以更好地反映它们的实际使用方式。 char32_t是目前唯一保证能够为其关联字符集中的每个字符保存一个代码点值的字符类型(C 和 C++ 标准wchar_t也声称可以,但这与现有做法相矛盾)。

看看你的例子,À 是 U+00C0 {LATIN CAPITAL LETTER A WITH GRAVE} (或者实际上是 A U+0041 {LATIN CAPITAL LETTER A} 后面跟着 ̀ U+0300 {COMBINING GRAVE ACCENT}?Unicode 很棘手)。U+00C0 的 UTF-8 编码为 0xC3 0x80。应该french_letter_A_1保持什么价值?它不能同时保存两个代码单元值。如果该值是代码点,那么我们要么处于只能(可移植地)支持 256 个字符的情况,要么更糟糕的是,有时值char8_t是代码点,有时它们是代码单元。

现实情况是,C 和 C++ 字符文字仅限于比基本源字符集中多几个字符。如果一个人正在编写仅英语的应用程序,这就足够了。但是对于现代应用程序,字符文字的用途有限。

正如 Nicol 已经说过的,处理基本源字符集之外的大多数字符需要对字符串进行真正的文本处理。不幸的是,C 和 C++ 标准在这方面没有提供太多帮助。这是SG16正在努力改进的地方。


推荐阅读