C ++ std:字符串比较编码问题

时间:2017-11-07 15:34:16

标签: c++ string encoding std utf

我认为std :: string与编码的比较存在问题。问题是我讨厌比较一个接收到的字符串,我不知道它有多少种类型的编码与一个带有异常字符的西班牙语字符串。我不能改变s_area.m_s_area_text所以我需要设置具有相同值的s2字符串,我不知道如何以通用的方式为其他追逐做。

std::string s2= "Versión de sistema";  
std::cout << s_area.m_s_area_text << std::endl;

for (const char* p = s2.c_str(); *p; ++p)
{
   printf("%02x", *p);
}
printf("\n");


for (const char* p = s_area.m_s_area_text.c_str(); *p; ++p)
{
   printf("%02x", *p);
}
printf("\n");

执行结果是:

Versi├│n de sistema
5665727369fffffff36e2064652073697374656d61
5665727369ffffffc3ffffffb36e2064652073697374656d61

显然,由于2个字符串的字节值不同,所以比较方法都失败了:strncmp,std :: string ==,std:sstring.comapre等。

知道如何触摸s_area.m_s_area_text字符串吗?

2 个答案:

答案 0 :(得分:0)

通常,通过检查字符串的原始字节来猜测字符串的编码是不可能的。此规则的例外是字节顺序标记(BOM)出现在字节流的开头。 BOM将告诉您字节的unicode编码和字节顺序。

顺便说一句,如果在将来的某个时候你决定需要一个规范的字符串编码(正如一些人在评论中指出的那样,这将是一个好主意)。有充分理由支持UTF-8作为C ++的最佳选择。有关详细信息,请参阅UTF-8 everywhere

答案 1 :(得分:0)

首先,两个正确比较两个字符串你至少需要知道它们的编码。在您的示例中,s_area.m_s_area_text碰巧使用UTF-8编码,而s2使用ISO / IEC 8859-1(Latin-1)。

如果您确定s_area.m_s_area_text将始终以UTF-8编码,您可以尝试使s2使用相同的编码,然后只进行比较。定义UTF-8编码字符串的一种方法是使用\u转义不在基本字符集中的每个字符。

std::string s2 = u8"Versi\u00F3n de sistema";
...
if (s_area.m_s_area_text == s2)
...

通过为源文件设置适当的编码并为编译器指定编码,也可以在不转义字符的情况下执行此操作。

正如@nwp所提到的,您可能还想在比较之前规范化字符串。否则,两个看起来相同的字符串可能具有不同的Unicode表示形式,这将导致您的比较产生错误的否定结果。 例如,“Versióndesistema”将不等于“Versióndesistema”。