почему сравнение двух строк в utf8 не правильно? - PullRequest
2 голосов
/ 22 августа 2011

У меня есть два слова, и оба имеют тип 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;
        }
}

первое слово - это термин, а второе слово - это слово; функция перегрузки as_utf8 ():

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

Ответы [ 3 ]

3 голосов
/ 22 августа 2011

Юникод сложнее, чем вы думаете. Есть комбинирующие символы, невидимые кодовые точки и что нет. Если две строки выглядят одинаково при печати, это не означает, что они идентичны между байтами.

Чтобы учесть все сложности Unicode, вам нужно использовать библиотеку строк с поддержкой Unicode. Одна из таких библиотек - ICU . Стандартная библиотека C ++ определенно не поддерживает Unicode. Вероятно, он может правильно считать символы в строках UTF-8, но это все.

2 голосов
/ 22 августа 2011

В Юникоде (а UTF-8 - Юникод), существует проблема композиции .Токен, подобный é, может быть представлен своей собственной кодовой точкой или кодовой точкой e, за которой следует ´.Может быть так, что один кодируется с использованием предварительной композиции (é), а другой - с помощью декомпозиции ().Оба будут отображаться одинаково.Чтобы избежать этой проблемы, следует нормализовать строки в одном из этих типов композиции.

Конечно, может быть другая проблема, но это одна из проблем, которая может привести к тому, что строки одинакового вида не будут сравниваться как равные.OTOH, если в вашем тексте нет символов вне ASCII, это вряд ли проблема.

Правильный способ сравнения строк - сначала нормализовать их.Вы можете сделать это в Python с помощью модуля unicodedata.

Стандартное техническое приложение Unicode # 15 описывает состав и нормализация в деталях.

0 голосов
/ 22 августа 2011

Попробуйте использовать std::wstring.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...