【问题标题】:why does eof() not work as I expect?为什么 eof() 不能按我的预期工作?
【发布时间】:2015-12-20 20:10:03
【问题描述】:
#include <iostream>
#include <fstream>

using namespace std;

int main() 
{
    ifstream in("input.txt");
    int i = 0,sum=0;
    char x;
    while (!in.eof()){
        in >> i;
        if (in.good()) {
            cout << "integer is " << i << endl; sum += i; 
        }
        if (in.fail()) {
            in.clear();
            in >> x;
            cout << "the char is " << x << endl;
        }
    }
    cout << sum;
    char z;
    cin >> z;
}

而我的 input.txt 是这样的:

熊:sdf 23 okI am fine 11q , 45

我的屏幕输出是这样的:

the last number 45 doesn't show up

那么这里发生了什么?为什么45被认为是一个out of file。如果我在 45 旁边立即添加一个 's',屏幕将显示两个 s,而不仅仅是一个。

【问题讨论】:

  • #inlcude -> #include

标签: c++ eof


【解决方案1】:

问题在于,在提取 45 的符号时,它会尝试在“5”之后提取符号(以检查数字是否继续进一步)并看到文件结尾,设置为 eofbit。这使得in.good() 测试失败。建议:

while (!in.eof()){
    in >> i;
    if ( in ) { //Not .good(), just conversion to bool

或者

while (!in.eof()){
    if ( in >> i; ) { //both extraction and checking in same operation

请记住,.good() 与检查流状态不同。 .good() 告诉流是否准备好进一步输入。 Bool 转换执行 ! .fail() 并检查 last 操作是否成功执行

【讨论】:

  • 所以,当最后一次 "in" 读取 45 时,它由 "std::ios::eof()" 设置。此时,.good() 失败,而! .fail() 仍然返回 true。
  • @JiehongJiang 是的。不要使用good() 来检查之前的操作是否成功。 goodeof 的用途都非常有限,您在使用它们之前应该三思而后行。在您的情况下,使用eof 是其中一种罕见的情况,但使用while (in.good()){ 而不是while (!in.eof()){ 会更好,因为它也捕获了关键流故障(坏位)。
  • 谢谢!这很有帮助。
【解决方案2】:

好吧,“eof()确实按预期工作,至少,我期望它如何工作:当流以某种方式触及文件末尾时它被设置。如果您的文件的最后一行实际上以 '5' 而不是换行符结束,则由于触摸换行符而停止读取整数并设置 std::ios_base::eofbit。由于std::ios::good() 返回false,如果设置了任何位,包含std::ios_base::failbit 将不会打印最后一个值。

一般来说,eof() 被误用的次数多于正确使用的次数。本质上,eof() 的唯一合理用途是验证是否已使用整个流,或者如果设置了eof(),则抑制错误消息,因为预期输入在流结束时失败。同样,std::ios::good() 通常也没什么用处。

【讨论】:

    猜你喜欢
    • 2015-07-25
    • 1970-01-01
    • 2020-06-07
    • 2020-01-10
    • 1970-01-01
    • 2021-05-30
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多