c++ - 为什么 '€' == '\€' 但 "€" != "\€" 和 u8"€" != u8"\€"
问题描述
在到处阅读 utf8 之后,我试图更改我的一些代码以使用 std::string。我假设如果我将 std::string 设置为 u8"€" (这是我键盘上的欧元符号 AltGr+4),std::string 将有 3 个字节包含欧元符号的 unicode 代码 (\U20AC)。它没有。考虑
std::string x[] = {"€", u8"€", u8"\€", "\u20AC", u8"\u20AC"}
size_t size[] = {x[0].size(), x[1].size(), x[2].size(), x[3].size(), x[4].size()};
如果我在调试器局部变量中查看结果,我会看到
x[] = {"€", "€", "â??", "€", "€"}
和
size[] = {1, 1, 3, 3, 3}
从我所看到的最后两个是唯一给我预期结果的。我显然错过了与字符串文字有关的东西,但我也很困惑调试器如何为前两个显示正确的字符串,因为它认为它们是一个字符长并且(int64_t(x[0].c_str()[0]) == int64_t(x[1].c_str()[0]) == -128
.
还有为什么 '€' == '\€' 但是 "€" != "\€" 和 u8"€" != u8"\€"。(编辑:忽略这个。Remy 在下面指出我的错误重新比较 char指针)。
结果还提出了一个问题 u8 字符串文字前缀的目的是什么?
在我恢复到 wchar_t 之前,有人可以解释一下吗?
我在使用 RAD studio 10.2 的 Windows 10 上。
编辑:使用字符映射工具对各种非 ASCII Unicode 字符进行了尝试。无法让它与他们中的任何一个一起工作。size() 始终为 1,并且调试器显示与我使用的字符不同的字符(通常是“?”)。我使用的是 Surface Pro 类型的封面,据我所知,无法使用键盘输入随机的 Unicode 字符(除了 €)。从现在开始为我严格反斜杠代码。很高兴我已经把它清理干净了,即使我浪费了一整天。谢谢大家。
解决方案
我假设如果我将 std::string 设置为 u8"€" (这是我键盘上的欧元符号 AltGr+4),std::string 将有 3 个字节包含欧元符号的 unicode 代码 (\U20AC)。它没有。
它应该,是的。前缀保证文字在u8
最终可执行文件中存储为 UTF-8,并且 U+20AC 在 UTF-8 中确实编码为 3 个字节。如果您看到不同的东西,那很可能是应该报告给 Embarcadero 的编译器错误。
我也很困惑调试器如何为前两个显示正确的字符串,因为它认为它们是一个字符长并且
(int64_t(x[0].c_str()[0]) == int64_t(x[1].c_str()[0]) == -128
.
第二个应该是 3 个字节,而不是 1 个字节。
由于两者都是 1 字节,显示只是偶然的。字符串文字没有前缀,因此使用编译器的默认 ANSI 字符集进行解释,在您的情况下,它必须恰好在字节 0x80 处具有欧元符号。
还有为什么 '€' == '\€' 但 "€" != "\€" 和 u8"€" != u8"\€"。
因为第一个是比较实际char
值,而另一个是比较原始char*
指针,而不是实际char
值。
结果还提出了一个问题 u8 字符串文字前缀的目的是什么?
正是您所期望的 - 它应该使编译器以 UTF-8 编码输出字符串文字的内容。
推荐阅读
- java - 作为作业的一部分,我想将查询参数字符串转换为 Java 中的树对象
- java - 有没有办法让 Jedis 自动为命令方法使用连接池?
- reactjs - 我将如何在 ReactJs 中编写这个渲染方法,这是一个面试问题?
- java - 如何在 NetBeans 中解决此错误“地址已在使用中”?
- html - 滑块无法居中
- android - 如何使初始屏幕上的图片在 1 秒后出现
- python - 访问函数中分配的变量
- ios - swift中的iMessage扩展
- elasticsearch - elasticsearch percolator 可以给出单词位置吗?
- python - 熊猫数据框仅返回第一行 JSON 数据?