我很难理解为什么while (cin.get(Ch))
没有看到EOF
。我在一个包含3个单词的文本文件中读取,当我调试我的WordCount时为3(正如我所希望的那样)。然后它回到while循环并卡住。 Ch
然后没有价值。我认为在换行后它会读取EOF
并突破。我不允许使用<fstream>
,我必须在DOS中使用重定向。非常感谢你。
#include <iostream>
using namespace std;
int main()
{
char Ch = ' ';
int WordCount = 0;
int LetterCount = 0;
cout << "(Reading file...)" << endl;
while (cin.get(Ch))
{
if ((Ch == '\n') || (Ch == ' '))
{
++WordCount;
LetterCount = 0;
}
else
++LetterCount;
}
cout << "Number of words => " << WordCount << endl;
return 0;
}
答案 0 :(得分:2)
while (cin >> Ch)
{ // we get in here if, and only if, the >> was successful
if ((Ch == '\n') || (Ch == ' '))
{
++WordCount;
LetterCount = 0;
}
else
++LetterCount;
}
这是一种安全且通用的方法,可以安全地重写代码并且只需进行很少的更改。
(你的代码很不寻常,试图扫描所有字符并计算空格和换行符。我将对一个稍微不同的问题给出更一般的答案 - 如何阅读所有单词。)
if(stream)
检查流是否已完成的最安全方法。谨防if(stream.good())
- 它并不总是按预期工作,有时会过早退出。 >>
中的最后一个char
不会将我们带到EOF,但>>
或int
中的最后一个string
将带我们去EOF。这种不一致可能令人困惑。因此,使用good()
或任何其他测试EOF的测试是不正确的。
string word;
while(cin >> word) {
++word_count;
}
if(cin)
和if(cin.good())
之间存在重要差异。前者是operator bool
conversion。通常,在这种情况下,您要测试:
“最后一次提取操作成功还是失败?”
这不与:
相同“我们现在在EOF吗?”
cin >> word
读完最后一个单词后,字符串为EOF。但是word
仍然有效且包含最后一个字。
TLDR:eof
位并不重要。 bad
位是。{1}}。这告诉我们最后一次提取失败了。
答案 1 :(得分:1)
程序将换行符和空格字符计为单词。在你的文件内容“这有趣!”我看到两个空格,没有换行符。这与观察到的输出一致,表示两个单词。
您是否尝试使用十六进制编辑器或类似内容查看文件以确定确切的内容?
如果循环中读取的最后一个字符是一个字母,您也可以将程序更改为再计一个字。这样您就不必使用换行符终止输入文件。
我没有解释您的循环终止问题。那段时间对我来说很好看。 istream::get(char&)
返回流引用。在while-condition中,根据编译器实现的C ++级别,operator bool
or operator void*
将应用于引用,以指示是否可以进一步读取。
从流中读取的标准习惯用语是
char c = 0;
while( cin >> c )
process(c);
如果没有严重的理由,我不会偏离它。
答案 2 :(得分:0)
在你的情况下,摆脱循环的正确方法是:
while (cin.good()) {
char Ch = cin.get();
if (cin.good()) {
// do something with Ch
}
}
尽管如此,可能有更好的方法来做你想做的事情。
答案 3 :(得分:0)
您输入的文件是
这很有趣!{EOF}
两个空格使WordCount增加到2 然后EOF,退出循环!如果添加新行,则输入文件为
this is fun!\n{EOF}
答案 4 :(得分:0)
我把你的程序加载到visual studio 2013中,将cin更改为一个fstream对象,打开一个名为stuff.txt的文件,其中包含确切的字符“这很有趣!/ n / r”,程序运行正常。如前面的答案所示,要小心,因为如果文本末尾没有a / n,程序将错过最后一个单词。但是,我无法复制悬挂在无限循环中的应用程序。所写的代码对我来说是正确的。
cin.get(char)返回对istream对象的引用,然后调用它的运算符bool(),当设置任何错误位时返回false。有一些更好的方法可以编写这段代码来处理其他错误条件......但是这段代码对我有用。