为什么utf8中两个字符串的比较不正确?

时间:2011-08-22 10:54:32

标签: c++ string compare

我有两个单词,两个都是std :: string类型,它们是unicode单词。它们是相同的,我的意思是当我将它们写入某个文件时,它们都具有相同的表示形式。但是当我调用word1.compare(word2)时,我得不到正确的结果。为什么他们不一样? 或者我应该使用另一个函数而不是比较来比较两个unicode字符串? 感谢

ifstream myfile;
    string term = "";
    myfile.open("homograph.txt");   
    istream_iterator<string> i(myfile);
    multiset<string> s(i, istream_iterator<string>());
    for(multiset<string>::const_iterator i = s.begin(); i != s.end(); i = s.upper_bound(*i))
    {           
        term = *i;      

    }


    pugi::xml_document doc;
    std::ifstream stream("words0.xml");
    pugi::xml_parse_result result = doc.load(stream);
pugi::xml_node words = doc.child("Words");

for (pugi::xml_node_iterator it = words.begin(); it != words.end(); ++it)
{       
        std::string wordValue = as_utf8(it->child("WORDVALUE").child_value());
        if(!wordValue.compare(term))
        {
        o << wordValue << endl;
        }
}

第一个词是&#34; term&#34;第二个词是wordValue; as_utf8()的重载函数是:

std::string wordNet::as_utf8(const char* str)
{
    return str;
} 

3 个答案:

答案 0 :(得分:3)

Unicode比你想象的要复杂得多。有组合字符,隐形代码点和什么不是。如果两个字符串在打印时看起来相同,则并不意味着它们是字节到字节相同的。

要考虑Unicode的所有复杂情况,您需要使用支持Unicode的字符串库。一个这样的库是ICU。 C ++标准库绝对不是Unicode感知的。它可能可以正确计算UTF-8字符串中的字符,但这就是它。

答案 1 :(得分:2)

在Unicode(和UTF-8是Unicode)中,存在 组合 的问题。像é这样的令牌可以由自己的代码点表示,也可以由代码点e后跟´表示。可能是一个使用预合成(é)编码而另一个使用分解()编码。两者通常以相同的方式显示。为了避免这个问题,我们应该对其中一种组合类型的字符串进行规范化。

当然,可能还有另一个问题,但这是一个问题,可以使相同的字符串不能比较相等。 OTOH,如果你的文字没有ASCII以外的任何字符,这几乎不是问题。

比较字符串的正确方法是首先将它们标准化。您可以使用unicodedata模块在​​Python中执行此操作。

Unicode Standard Technical Appendix #15详细描述了 组合 规范化

答案 2 :(得分:-4)

请尝试使用std::wstring