如何在utf8中获得代码点文字
How do I get a code point literal in utf8
我最近才意识到,C++17的u8
字符前缀并不适用于所有utf8代码点,只适用于ASCII部分。
来自cppreference
UTF-8字符文字,例如
u8'a'
。这种文字的类型为char
,其值等于ISO 10646的c-char代码点值,前提是代码点值可以用单个UTF-8代码单元表示。如果c-char不在Basic Latin或C0 Controls Unicode块中,则程序格式不正确。
auto hello = u8'嗨'; // ill-formed
auto world = u8"世"; // not a character
auto what = 0xE7958C; // almost human-readable
auto wrong = u8"錯"[0]; // not even correct
如何简洁地获得utf8中的代码点文字?
编辑:对于那些想知道如何存储utf8代码点的人来说,我认为一种合理的方法就像Golang这样做。基本想法是在只需要单个代码点的情况下,将单个代码点存储在32位类型中。
编辑2:从有用的评论中提出的论点来看,没有理由让编码的utf8一直保持在32位类型中。要么对其进行解码(utf32,前缀为U
),要么将其编码在前缀为u8
的字符串中。
如果您想要一个代码点,那么您应该使用char32_t
和U
作为前缀:
auto hello = U'嗨';
UTF-8将代码点存储为8位代码单元的序列。C++中的char
是一个代码单元,因此它不能存储整个Unicode代码点。如果提供需要存储多个代码单元的代码点,则字符文字上的u8
前缀不会编译,因为一个字符文字只能产生一个char
。
如果您想要一个用UTF8编码的Unicode代码点,那么您想要的是字符串文字,而不是字符文字:
auto hello = u8"嗨";
我觉得合理的一种方式就像Golang这样做。
好吧,你没有用Go,是吗?
在C++中,如果你要求一个字符文字,那么你指的是该大小类型的单个对象。u8
文字将始终为char
。它的类型不会因字面意思而有所不同。你要求一个文字,你得到一个文字。
从你链接到的网站上可以清楚地看到,Go实际上根本没有UTF-8字符的概念。它只是具有字符文字,所有这些都是32位值。实际上,Go中的所有字符文字的行为都类似于U''
。
在C++中,一个字符文字恰好是一个字符对象<C++术语中的em>字符对象对应于Unicode中的代码单元。UTF-8的某些代码点需要多个代码单元。因此,并不是所有的UTF-8代码点都可以用一个字符对象来表示。可表示的代码点是Basic Latin和C0 Control块。
要表示任何UTF-8代码点,您需要一个代码单元数组,即字符串。字符串文字有一个类似的前缀:u8"☺"
。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 如何在utf8中获得代码点文字
- 为什么我的拆卸C 代码使用指令指针和偏移来获取字符串文字
- 我是否应该为代码中的重复文字定义常量
- 在这段代码中,是否有理由对字符串文字使用const_cast
- 为什么此代码输出文字"n"而不是换行符?