首页 > 解决方案 > Qt C++ macOS 问题。我正在使用函数 .find("a word") 在多集中搜索单词,它适用于 windows 但不适用于 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 编码的。

字典.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

字典.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;
        }
    }
}

主文件

#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

标签: c++macosiostream

解决方案


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

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

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


推荐阅读