C 比较文本文件和分段故障(核心倾倒)

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

本文关键字:核心 故障 分段 比较 文本 文件      更新时间:2023-10-16

我在作业方面遇到了麻烦,我在堆栈和Google上进行了搜索,但无法弄清楚这些问题。

现在,到目前为止,我唯一拥有的代码是要求用户放入句子,然后将句子分解为不同的字符串。我还需要将其与我中途收到的文本文件进行比较。

第一个问题:我将单词分为不同字符串的方法有时只能起作用。例如,当我写"历史人物"时,它告诉我有分割的错误,但是如果我输入"历史人物"(最后一个空间),则可以正常工作。我很困惑问题是什么。

第二个问题是我无法弄清楚如何将字符串与线路进行比较,它似乎将整个文件存储在我的字符串变量"文本"中。

#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;
}

当我写"历史人物"时,它会告诉我有分割的错误,但是如果我输入"历史人物"(结尾处的空间),它可以正常工作

很容易。您的while循环在字符串上运行,直到找到一个空间。但是,如果没有空间怎么办?循环会终止吗?不 - 它将一直持续到最终在内存,崩溃或其他东西中找到一个空间字符(这是不确定的行为,因此基本上一切都会发生,还可以在输出结束时附加一个感叹号)。如何解决?检查您是否在字符串的末端。

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

或使用完全不同的方法首先将字符串分开(请在此处查看此答案)。

到第二个问题。从文件中读取对我来说还可以,但是不知道文件的内容看起来我无法真正为您提供帮助。

根据您的代码,我希望该文件看起来有些类似:

noun1 noun2 noun3 noun4 etc.

由于将getline的定界符设置为一个空间:getline(inputfile, text, ' ')。这意味着文件中的所有名词均由一个空间分开,并以一行列出。是这样吗?不?好吧,只需将定界符更改为您在文件本身中使用的正确定界符即可。(顺便说一句。如果每个名词都在单独的行中列出,则无需指定定界线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;

您还听说过干燥原则吗?您的4时循环看起来有点相似,不是吗?您可以编写一个函数来执行此操作,然后将其称为4次(或者,如前所述,使用完全不同的方法)。