C++ 比较文本文件和分段错误(核心转储)

C++ comparing text file and segmentation fault (core dumped)

我在分配时遇到了问题,我搜索了整个堆栈 google 但无法找出问题所在。

目前,我唯一的代码是要求用户输入一个句子,然后将句子分成不同的字符串。而且我还需要将它与我中途获得的文本文件进行比较。

第一个问题:我将单词拆分成不同字符串的方法有时会奏效。例如,当我写 "history people" 时,它告诉我存在分段错误,但是如果我输入 "history people "(最后是 space),它就可以正常工作。我很困惑是什么问题。

第二个问题是我不知道如何逐行比较我的字符串和文本文件,它似乎将整个文件存储到我的字符串变量 "text".

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int noun(string n)
{
    ifstream inputfile;
    bool found = false; // set boolean value to false first
    string text;
    inputfile.open("nouns"); // open text file
    if (!inputfile.is_open()) 
    { // checks to make sure file is open
        cout << "Error" << endl;
    }

    while (getline(inputfile,text,' ')) 
    {
        if (n == text)
        {
            found = true;
            cout << text;
        } 
    }
    inputfile.close(); // close the file
    return found; // return true or false
}

int main ()
{
    string sent;
    string word1, word2, word3, word4; // strings to parse the string 'sent'
    cout << "Please enter a sentence" << endl;
    getline (cin, sent);

    int w1, w2, w3, w4 = 0; // positions in relation to the string
    while (sent[w1] != ' ')
    { // while loop to store first word
        word1 += sent[w1];
        w1++;
    }

    w2 = w1 + 1;
    while (sent[w2] != ' ')
    { // while loop to store second word
        word2 += sent[w2];
        w2++;
    }

    w3 = w2 + 1;
    while (sent[w3] != ' ')
    { // while loop to store 3rd word
        word3 += sent[w3];
        w3++;
    }

    w4 = w3 + 1;
    while (sent[w4] != sent[-1])
    { // while loop to store 4th word
        word4 += sent[w4];
        w4++;
   }

    cout << word1;

    if (sent.empty())
    { // empty set returns "invalid sentence"
        cout << "Invalid Sentence" << endl;
    }
    else if (noun(word1) == true)
    {
        cout << "This is valid according to rule 1" << endl; 
    }

    return 0;
}

when I write "history people" it tells me theres a segmentation fault, but if I type in "history people " (with the space at the end), it works fine

好简单。您的 while 循环遍历字符串,直到找到 space。但是如果没有space呢?循环会终止吗?不 - 它会继续,直到它最终在内存中的某处找到一个 space 字符或崩溃或其他东西(它是 undefined behavior 所以基本上一切都可能发生,还在输出的末尾附加一个感叹号)。如何解决?检查你是否在字符串的末尾。

while (sent[w1] != ' ' && w1 < sent.size()) ...

或者首先使用完全不同的方法来拆分字符串(看看这个答案here)。

第二个问题。从文件中读取对我来说看起来没问题,但不知道文件的内容如何,​​我无法真正帮助你。

根据您的代码,我希望该文件看起来有点像:

noun1 noun2 noun3 noun4 etc.

因为您将 getline 的分隔符设置为 space: getline(inputfile, text, ' ')。这意味着文件中的所有名词都由 space 分隔并全部列在一行中。是这样吗?不?那么只需将分隔符更改为您在文件本身中使用的正确分隔符。 (顺便说一句。如果每个名词都在单独的行中列出,则不需要指定分隔符 getline(inputfile, text)

此外,如果您检查文件是否无法打开,则不要继续阅读,而是停止执行该函数。

if (!inputfile.is_open()) { // checks to make sure file is open
    cout << "Error" << endl;
    return false; // return for example or throw an exception
}

但是您的应用程序仍然存在其他问题,例如在处理之前检查用户输入,您不需要关闭 ifstream 它的析构函数会处理它。

或者您认为 int w1, w2, w3, w4 = 0 的作用是什么?将所有变量设置为 0?你猜怎么着,不。 w4 已初始化并设置为 0,但所有其他值均未初始化,并且在任何地方再次使用它们都会调用 UB。所以这个 sent[w1] 是未定义的行为,这个 w1++ 是,这个 w2 = w1 + 1 是,并且 ...

始终确定并以正确的方式做事。每个变量声明一行并直接初始化它们。

int w1 = 0;
int w2 = 0;
int w3 = 0;
int w4 = 0;

你也听说过DRY原理吗?您的 4 个 while 循环看起来有点相似,不是吗?您可以编写一个函数来执行此操作,然后调用它 4 次(或者如我之前所说,使用完全不同的方法)。