2 Stimmen

Warum ist der Vergleich von zwei Zeichenfolgen in UTF-8 nicht korrekt?

Ich habe zwei Wörter und beide sind vom Typ std::string und es handelt sich um Unicode-Wörter. Sie sind gleich, das heißt, wenn ich sie in eine Datei schreibe, haben sie beide die gleiche Darstellung. Aber wenn ich word1.compare(word2) aufrufe, erhalte ich nicht das richtige Ergebnis. Warum sind sie nicht gleich? Oder sollte ich eine andere Funktion anstelle von compare verwenden, um zwei Unicode-Strings zu vergleichen? Dank

ifstream myfile;
    string term = "";
    myfile.open("homograph.txt");   
    istream_iterator i(myfile);
    multiset s(i, istream_iterator());
    for(multiset::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;
        }
}

Das erste Wort ist "term" und das zweite Wort ist wordValue; Die Überlastfunktion von as_utf8() lautet:

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

4voto

Rudy Velthuis Punkte 27899

Im Unicode (und UTF-8 ist Unicode) gibt es das Problem der Zusammensetzung. Ein Token wie é kann durch seinen eigenen Codepunkt oder durch den Codepunkt e gefolgt von ´ dargestellt werden. Es könnte sein, dass das eine durch Präkomposition (é) und das andere durch Dekomposition () codiert ist. Beide werden normalerweise auf die gleiche Weise angezeigt. Um das Problem zu vermeiden, sollte man Zeichenketten auf einem dieser Kompositionstypen normalisieren.

Natürlich könnte es ein anderes Problem geben, aber das ist eines der Probleme, die dazu führen können, dass gleich aussehende Zeichenketten nicht als gleich betrachtet werden. Andererseits, wenn Ihr Text keine Zeichen außerhalb des ASCII-Bereichs enthält, ist dies kaum das Problem.

Der richtige Weg, um die Zeichenketten zu vergleichen, besteht darin, sie zuerst zu normalisieren. In Python können Sie dies mit dem unicodedata Modul tun.

Der Unicode Standard Technische Anhang #15 beschreibt Zusammensetzung und Normalisierung im Detail.

3voto

Unicode ist komplizierter als man denkt. Es gibt kombinierende Zeichen, unsichtbare Codepunkte und was auch immer. Wenn zwei Zeichenfolgen gleich aussehen, wenn sie gedruckt werden, bedeutet das nicht, dass sie byte-für-byte identisch sind.

Um alle Komplikationen von Unicode zu berücksichtigen, müssen Sie eine Unicode-fähige Zeichenfolienbibliothek verwenden. Eine solche Bibliothek ist ICU. Die C++ Standardbibliothek ist definitiv nicht Unicode-fähig. Es kann wahrscheinlich korrekt die Zeichen in einer UTF-8 Zeichenfolge zählen, aber das war es auch schon.

-4voto

weekens Punkte 7734

Versuchen Sie stattdessen, std::wstring zu verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X