Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么utf8中两个字符串的比较不正确?_C++_String_Compare - Fatal编程技术网

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

C++ 为什么utf8中两个字符串的比较不正确?,c++,string,compare,C++,String,Compare,我有两个单词,它们都是std::string类型的,都是unicode单词。它们是一样的,我的意思是,当我将它们写入某个文件时,它们都具有相同的表示形式。但是当我调用word1.compare(word2)时,我没有得到正确的结果。为什么它们不一样? 或者我应该使用另一个函数而不是compare来比较两个unicode字符串? 谢谢 在Unicode中(UTF-8是Unicode),存在组合问题。像é这样的标记可以由它自己的代码点表示,或者由代码点e后跟'表示。可能是一个使用预合成(e)编码,另

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

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

当然,可能还有另一个问题,但这是使等长字符串不能作为相等字符串进行比较的问题之一。OTOH,如果您的文本没有ASCII以外的任何字符,这几乎不是问题所在

比较字符串的正确方法是首先对其进行规范化。您可以在Python中使用
unicodedata
模块来实现这一点


详细描述了组合规范化

Unicode比您想象的更复杂。有组合字符、不可见的代码点等等。如果两个字符串在打印时看起来相同,并不意味着它们是字节对字节相同的


要考虑到Unicode的所有复杂性,您需要使用支持Unicode的字符串库。一个这样的图书馆就是。C++标准库绝对不是Unicode感知的。它可能可以正确计算UTF-8字符串中的字符数,但仅此而已。

尝试使用
std::wstring

您所说的“表示”是什么意思?两个字符串打印的内容相同吗?因为这毫无意义
std::string
内部可以有
\0
,如果两个字符串都有
\0
,并且它们在
\0
之后不同,则
比较
将返回
false
。向我们展示一些代码+示例(+文件和您如何打开/读取它)。当您写出它们时,您使用的是什么字符集?其中一个单词是波斯语单词,我将其写入某个文件,并使用istream_迭代器(文件)读取。另一个字符串是pugixml::child_value()的返回值,它基本上是pugi::char_t*类型,然后我将其转换为字符串suing,因为我编辑了我的问题,并在其中添加了一些细节as-utf8()函数的结果可能是string,我不能使用函数as-wide(),因为这需要不同的参数mbstowcs()本机字符的函数可能就是您所需要的。wstring不能神奇地解决任何问题。除了需要将编码转换为utf16或utf32之外,复合图示符的注意事项仍然存在。我的问题是我无法将std::string转换为std::wstring@aliakbarian,
std::wstring(mbstowcs(std::string.c_str())
(嗯,不完全是这样,但只是为了展示一个想法)当我将单词放入文本文件并将文件保存为utf8时,我没有问题,我认为问题在于函数-utf8(),我不知道它返回什么?没错,
as\u utf8()
不会神奇地将您手头的任何编码重新编码为UTF-8。如果要将字符串重新编码为UTF-8,则需要使用可以进行重新编码的库。
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;
        }
}
std::string wordNet::as_utf8(const char* str)
{
    return str;
}