为什么'€'=='\€'但为什么“€”!=“ \€”和u8“€”!= u8“ \€”

时间:2019-09-09 17:22:12

标签: c++ string-literals

在所有地方都阅读过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“ \€”。(编辑:忽略此。雷米在下面指出了我的错误重新比较char指针)。

结果还引出了一个问题,即u8字符串文字前缀的用途是什么?

在我恢复到wchar_t之前有人可以解释吗?

我在Windows 10上使用RAD studio 10.2。

编辑:使用字符映射工具尝试了各种非ASCII Unicode字符。无法与任何人一起使用。 size()始终为1,调试器显示的字符与我使用的字符不同(通常为'?')。我使用的是Surface Pro类型的保护套,但据我所知,无法使用键盘输入随机的Unicode字符(除€外)。从现在开始,严格为我反斜杠代码。很高兴即使我浪费了一整天,我也已经清除了它。谢谢大家

1 个答案:

答案 0 :(得分:2)

  

我假设如果将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编码输出字符串文字的内容。