我在作业方面遇到了麻烦,我在堆栈和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次(或者,如前所述,使用完全不同的方法)。