繁体   English   中英

简单的C ++不能读取EOF

[英]Simple C++ not reading EOF

我很难理解为什么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;
}
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,但最后一个>>进入一个intstring 将把我们带到EOF。 这种不一致可能令人困惑。 因此,使用good()或测试EOF的任何其他测试是不正确的。

string word;
while(cin >> word) {
   ++word_count;
}

if(cin)if(cin.good())之间有一个重要的区别。 前者是operator bool转换 通常,在此上下文中,您要测试:

“最后一次提取操作成功还是失败?”

这是一样的:

“我们现在在EOF吗?”

在通过cin >> word读取最后一个单词后,该字符串处于EOF。 但这个word仍然有效,并包含最后一个字。

TLDR: eof位并不重要。 bad是。 这告诉我们最后一次提取失败了。

计数

该程序将换行符和空格字符计为单词。 在你的文件内容“这有趣!” 我看到两个空格,没有换行符。 这与观察到的输出结果一致,表示两个单词。

您是否尝试使用十六进制编辑器或类似内容查看文件以确定具体内容?

如果循环中读取的最后一个字符是一个字母,您也可以更改您的程序以再计一个字。 这样您就不必使用换行符终止输入文件。

循环终止

我没有解释你的循环终止问题。 那段时间对我来说很好看。 istream::get(char&)返回流引用。 在while-condition中,根据编译器实现的C ++级别, operator booloperator void*将应用于引用,以指示是否可以进一步读取。

成语

从流中读取的标准习语是

char c = 0;
while( cin >> c )
   process(c);

没有严肃的理由,我不会偏离它。

在你的情况下,摆脱循环的正确方法是:

while (cin.good()) {
  char Ch = cin.get();
  if (cin.good()) {
    // do something with Ch
  }
}

也就是说,可能有更好的方法来做你想做的事情。

你输入的文件是

这很有趣!{EOF}

两个空格使WordCount增加到2然后EOF,退出循环! 如果添加新行,则输入文件为

this is fun!\n{EOF}

我把你的程序加载到visual studio 2013中,将cin更改为一个fstream对象,打开一个名为stuff.txt的文件,其中包含确切的字符“这很有趣!/ n / r”,程序运行正常。 如前面的答案所示,要小心,因为如果文本末尾没有a / n,程序将错过最后一个单词。 但是,我无法复制悬挂在无限循环中的应用程序。 写的代码对我来说是正确的。

cin.get(char)返回对istream对象的引用,然后调用它的运算符bool(),当设置任何错误位时返回false。 有一些更好的方法来编写此代码来处理其他错误条件......但此代码适用于我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM