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 次(或者如我之前所说,使用完全不同的方法)。
我在分配时遇到了问题,我搜索了整个堆栈 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 次(或者如我之前所说,使用完全不同的方法)。