C ++:Unicode字符串文字的可移植性

时间:2018-08-15 23:36:55

标签: c++ unicode string-literals

在gcc上进行调试时,我发现Unicode文字u"万不得已"被表示为u"\007\116\015\116\227\137\362\135"。这很有意义-是0x4E07,八进制的0x4E是116。

现在在基于Intel的Macbook上的Apple LLVM 9.1.0上,我发现相同的文字不能作为相同的字符串处理,即:

u16string{u"万不得已"} == u16string{u"\007\116\015\116\227\137\362\135"}

truefalse。我仍然使用小端系统,所以我不知道发生了什么。

NB。我不尝试使用对应关系u"万不得已" == u"\007\116\015\116\227\137\362\135"。我只想了解发生了什么。

1 个答案:

答案 0 :(得分:7)

  

我发现Unicode文字u"万不得已"表示为u"\007\116\015\116\227\137\362\135"

不,实际上不是。这就是为什么...

u"..."字符串文字在所有平台上均被编码为基于char16_t的UTF-16编码字符串(这就是u前缀的特定含义)。

u"万不得已"由以下UTF-16代码单元序列表示:

4E07 4E0D 5F97 5DF2

在小端系统上,该UTF-16序列由以下原始字节序列表示:

07 4E 0D 4E 97 5F F2 5D

以八进制表示,只有当使用基于 "\007\116\015\116\227\137\362\135" 的字符串时,char才能表示(请注意,缺少字符串前缀或u8在此示例中也可以使用)。

u"\007\116\015\116\227\137\362\135"不是基于char的字符串!这是一个基于 char16_t的字符串,其中每个八进制数字代表一个单独的UTF-16代码单元。因此,此字符串实际上代表此UTF-16码元序列:

0007 004E 000D 004E 0097 005F 00F2 005D

这就是为什么您的两个u16string对象未将相同的字符串值进行比较的原因。因为它们确实不相等。

您可以在此处看到此操作:Live Demo