Qt C++ macOS 问题。我正在使用函数 .find("a word") 在多重集中搜索单词,它适用于 windows 但不适用于 mac

Qt C++ macOS problem. I am searching for words in multiset with function .find("a word") it works on windows but not on mac

我写了一些代码来加载一些包含单词列表(一个单词 pr 行)的文件。每个单词都被添加到一个多重集中。后来我尝试用 multiset.find("aWord") 搜索多重集。我在哪里寻找多重集中的单词和单词的子串。

如果我在 windows 系统上用 qt 编译这段代码,它可以正常工作。

但是如果我在我的 mac !

上用 qt 编译它就不能工作

我的目标是让它在我的 mac.

上通过 qt 运行

我正在 macbook Air(2018 年初 13 英寸)

macOS Majave version 10.14.4 instalation
Buil version 18E226
local 18.5.0 Darwin Kernel Version 18.5.0: Mon Mar 11 20:40:32 PDT 
2019; root:xnu-4903.251.3~3/RELEASE_X86_64 x86_64

使用qt安装: QTKit:

  Version: 7.7.3
  Obtained from: Apple
  Last Modified: 13/04/2019 12.11
  Kind: Intel
  64-Bit (Intel): Yes
  Get Info String: QTKit 7.7.3, Copyright 2003-2012, Apple Inc.
  Location: /System/Library/Frameworks/QTKit.framework
  Private: No

和xcode安装:

  Xcode 10.2
  Build version 10E125 

我试过打印出来: 我正在搜索的每个字符串 我应该在多重集中找到的每个字符串都是十六进制格式 并得出一些字母不匹配的结论。 在那里的十六进制值。尽管我认为我的整个系统 运行 utf-8 并且文件也是 utf-8 编码的。

Dictionary.h

  #ifndef DICTIONARY_H
  #define DICTIONARY_H
  #include <iostream>
  #include <vector>
  #include <set>

  class Dictionary
  {
  public:
      Dictionary();
      void SearchForAllPossibleWordsIn(std::string searchString);

  private:
      std::multiset<std::string, std::less<std::string>> mDictionary;

      void Initialize(std::string folder);
      void InitializeLanguage(std::string folder, std::string languageFileName);
  };

  #endif // DICTIONARY_H

Dictionary.cpp

#include "Dictionary.h"
#include <vector>
#include <set>
#include <iostream>
#include <fstream>
#include <exception>

Dictionary::Dictionary()
{
    Initialize("../Lektion10Projekt15-1/");
}

void Dictionary::Initialize(std::string folder)
{
    InitializeLanguage(folder,"da-utf8.wl");
}

void Dictionary::InitializeLanguage(std::string folder, std::string languageFileName)
{
    std::ifstream ifs;

    ifs.open(folder+languageFileName,std::ios_base::in);
    if (ifs.fail()) {
        std::cerr <<"Error! Class: Dictionary. Function: InitializeLanguage(...). return: ifs.fail to load file '" + languageFileName + "'"  << std::endl;
    }else {
        std::string word;

        while (!ifs.eof()) {
            std::getline(ifs,word);

            mDictionary.insert(word);
        }
    }
    ifs.close();
}

void Dictionary::SearchForAllPossibleWordsIn(std::string searchString)
{
    std::vector<std::string> result;

    for (unsigned int a = 0 ; a <= searchString.length(); ++a) {
        for (unsigned int b = 1; b <= searchString.length()-a; ++b)     {

            std::string substring = searchString.substr(a,b);

            if (mDictionary.find(substring) != mDictionary.end())
            {
                result.push_back(substring);
            }
        }
    }

    if (!result.empty()) {
        for (unsigned int i = 0; i < result.size() ;++i) {
            std::cout << result[i] << std::endl;
        }
    }
}

main.cpp

#include <iostream>
#include "Dictionary.h"

int main()
{
    Dictionary myDictionary;

    myDictionary.SearchForAllPossibleWordsIn("byggearbejderen");

    return 0;
}

我尝试更改 main.cpp

中的以下行
    myDictionary.SearchForAllPossibleWordsIn("byggearbejderen");

to (OBS: 单词列表中的第一个单词是byggearbejderen)

    std::ifstream ifs;
    ifs.open("../Lektion10Projekt15-1/da-utf8.wl",std::ios::in);
    if (ifs.fail()) {
        std::cerr <<"Error!" << std::endl;
    }else {
        std::getline(ifs,searchword);
    }
    ifs.close();
    myDictionary.SearchForAllPossibleWordsIn(searchword);

然后在 main.cpp 添加 som 以十六进制值形式打印出预期的字符串和子字符串。

    std::cout << " cout as hex test:" << std::endl;

    myDictionary.SearchForAllPossibleWordsIn(searchword);

    std::cout << "Suposet search resul for ''bygearbejderen''" << std::endl;

    for (char const elt: "byggearbejderen")
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elt) << "  ";
    std::cout << "byggearbejderen" << std::endl;

    for (char const elt: "arbejderen")
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elt) << "  ";
    std::cout  << "arbejderen" << std::endl;

    for (char const elt: "ren")
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elt) << "  ";
    std::cout  << "ren" << std::endl;

    for (char const elt: "en")
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elt) << "  ";
    std::cout  << "en" << std::endl;

    for (char const elt: "n")
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elt) << "  ";
    std::cout  << "n" << std::endl;

并且还在 Dictonary.cpp

的结果输出中添加了相同的打印
std::cout << "result of seartchword as hex" << std::endl;
if (!result.empty()) {
    for (unsigned int i = 0; i < result.size() ;++i)
    {
        for (char const elt: result[i] )
        {
            std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(elt) << "  ";
        }
        std::cout  << result[i] << std::endl;


    }
}

给出了以下输出:

result of seartchword as hex
ffffffef  ffffffbb  ffffffbf  62  79  67  67  65  61  72  62  65  6a  64  65  72  65  6e  0d  byggearbejderen
61  72  62  65  6a  64  65  72  65  6e  0d  arbejderen
72  65  6e  0d  ren
65  6e  0d  en
6e  0d  n
Suposet search resul for ''bygearbejderen''
62  79  67  67  65  61  72  62  65  6a  64  65  72  65  6e  00  byggearbejderen
61  72  62  65  6a  64  65  72  65  6e  00  arbejderen
72  65  6e  00  ren
65  6e  00  en
6e  00  n

我注意到有些值不同。 我不知道为什么我在 macOS 时会出现这种情况,但在 windows 时却不是这种情况。我不知道我的环境中是否有任何编码设置需要更改或设置正确。

我希望我的 main.cpp 看起来像这样:

#include <iostream>
#include "Dictionary.h"

int main()
{
    Dictionary myDictionary;

    myDictionary.SearchForAllPossibleWordsIn("byggearbejderen");

    return 0;
}

导致以下输出:

byggearbejderen
arbejderen
ren
en
n

文本文件的行尾在 Windows 上与在 Mac 上不同。 Windows 使用两个 CR/LF 字符(分别为 ASCII 代码 13 和 10)。旧 Macs 单独使用 CR 字符,Linux 系统仅使用 LF。如果您在 Windows 上创建文本文件,然后将其复制到您的 Mac,行尾可能无法正确处理。

如果您查看输出中的最后一个字符,您会发现它是一个 0d,即 CR 字符。我不知道您是如何生成该输出的,但是 Mac 上的 getline 可能将其视为普通字符,并将其包含在已读入的字符串中。

最简单的解决方案是预先处理该文本文件以使行尾正确,或者在读入单词后将 CR 从单词末尾去除。