C++ 如何正确声明变音字母的字符?

C++ 如何正确声明变音字母的字符?,c++,visual-c++,utf-8,utf,c++20,C++,Visual C++,Utf 8,Utf,C++20,我尝试使用新的char8\t类型初始化一些变音拉丁字母: constexpr char8_t french_letter_A_1 = 'À';//does not function properly 但是,Visual Studio 2019建议我在当前代码页“”中无法表示以下由通用字符名“\u(名称)”表示的“字符”,并且无法正确显示该字符;如果我尝试显式地将字符声明为u8字符,如: constexpr char8_t french_letter_A_2 = u8'Â';//has erro

我尝试使用新的
char8\t
类型初始化一些变音拉丁字母

constexpr char8_t french_letter_A_1 = 'À';//does not function properly
但是,Visual Studio 2019建议我在当前代码页“”中无法表示以下由通用字符名“\u(名称)”表示的“字符”,并且无法正确显示该字符;如果我尝试显式地将字符声明为
u8
字符,如:

constexpr char8_t french_letter_A_2 = u8'Â';//has error
它甚至抛出一个错误“UTF-8字符的文字值不能占用多个代码单元”
;但非变音字母可以成功地解释为UTF-8:

constexpr char8_t french_letter_A_0 = u8'A';//but ASCII letters are fine
我想知道如何使用Visual C++正确声明UTF-8字符。。。或者我误解了char8\u t的概念,应该用别的东西来代替


编辑:我理解
char8\t
不支持那些非ASCII字符。我应该改用什么字符类型?

UTF-8是Unicode码点的编码。在UTF-8中,一个码点被分解成一个或多个“八位字节”(8位字),称为UTF-8码单元。表示UTF-8代码单元的C++20类型是
char8\u t

单个
char8\u t
仅为一个UTF-8代码单元。因此,它只能表示UTF-8编码仅占用1个代码单元的Unicode码点。Visual Studio告诉您,您试图存储在
char8\t
中的“角色”需要超过1个代码单元,因此不能以这种类型存储。UTF-8在单个代码单元中编码的唯一Unicode代码点是ASCII代码点


在处理UTF-8(或任何非UTF-32的Unicode编码)时,不处理“字符”;处理字符串:代码单元的连续序列。任何时候你想要处理UTF-8,你都应该使用某种基于
char8\u t
的字符串类型。

char8\u t
,比如
char
signed char
,和
unsigned char
,大小为1字节。在大多数平台上(但不是全部!),这意味着它是一种8位类型,只能容纳256个离散值。Unicode 12.1定义了137994个字符。显然,它们不可能全部放在一个
char8\t
值中

遗憾的是,C和C++的“字符”类型是不好的。如果我们用现代术语设计一种新的语言,我们会给它们命名为
code\u单元的一些变体,因为这更好地反映了它们的实际使用方式<代码> CAR32×T/<代码>是目前唯一保证的字符集,它可以为其关联字符集中的每个字符保存代码点值(C和C++标准声称, WCARGYTT 也可以,但这与现有的实践相矛盾)。
看看你的例子,À是U+00C0{拉丁文大写字母A和GRAVE}(或者它实际上是一个U+0041{拉丁文大写字母A}后跟̀U+0300{组合GRAVE重音}?Unicode很难做到这一点)。U+00C0的UTF-8编码为0xC3 0x80。
法语字母\u A\u 1
应该保留什么值?它不能同时保存两个代码单位值。如果该值是代码点,那么我们要么只能(可移植地)支持256个字符,要么更糟糕的是,
char8\t
的值有时是代码点,有时是代码单位

实际情况是C和C++字符文字被限制为比字符数少一些。如果一个人只写英文申请,这就足够了。但在现代应用中,字符文字的用途有限


正如Nicol已经指出的,处理基本源字符集之外的大多数字符需要对字符串进行真正的文本处理。不幸的是,C和C++标准在这里没有提供太多帮助。这是一项正在努力改进的工作。

那么,我应该为非ASCII字符使用什么字符类型呢?@relaverix:正如我所说的:“当处理UTF-8时,你不处理“字符”;你处理字符串……你应该使用某种基于字符的字符串类型。”或者换句话说,UTF-8是不存在的“性格“从你的意思来说。那么我应该用
wchar
来表示那些重音字母吗?”?如果是的话,我应该像
L'À
或类似的东西一样声明它们吗?如果不是,哪种字符类型最能代表它们?@relaverix:。。。我不知道怎样才能把事情说清楚。不要使用字符!使用字符串。在处理任何Unicode编码时,不应处理任何类型的固定大小的“字符”。不,
wchar\u t
char16\u t
没有帮助,因为它们中的许多Unicode代码点无法放入一个16位字中。不要再试图扮演角色了。还有一些书写重音字母的方法需要多个Unicode代码点<代码>u8“À”
是您应该创建、使用和操作的内容。只是想添加一条非Nicol-Bolas的评论,以同意Nicol是完全正确的。根据定义,如果您使用Unicode,那么您使用的就是字符串。没有“Unicode字符”,只有字符串。我这样说是因为我在书中修辞学地问,“的第一个字符是什么?”ﷻ”? “fiff”的第一个字符是什么