eof() 不好的做法?[复制]

eof() bad practice? [duplicate]

提问人:Sam 提问时间:4/30/2011 最后编辑:CommunitySam 更新时间:8/6/2016 访问量:21485

问:

这个问题在这里已经有答案了:
12年前关闭。

可能的重复为什么循环条件中的 iostream::
eof 被认为是错误的?

因此,我一直在许多需要文件输入的程序中使用该函数,我的教授说它很好用,但 SO 上的一些人说我不应该在没有真正说明原因的情况下使用它。所以我想知道,有充分的理由吗?eof()

C++ EOF

评论

0赞 Oliver Charlesworth 4/30/2011
我认为你是说功能?feof()
2赞 Puppy 4/30/2011
他可能指的是 iostream::eof() 一个。

答:

36赞 Erik 4/30/2011 #1

您可以使用它来测试它报告的确切条件 - 您是否尝试读取文件末尾。不能使用它来测试是否有更多输入要读取,或者读取是否成功,这些都是更常见的测试。eof

错:

while (!cin.eof()) {
  cin >> foo;
}

正确:

if (!(cin >> foo)) {
  if (cin.eof()) {
    cout << "read failed due to EOF\n";
  } else {
    cout << "read failed due to something other than EOF\n";
  }
}

评论

0赞 Sam 4/30/2011
但是,如果您已经阅读了文件的末尾,难道不应该没有剩余的信息吗?
4赞 Erik 4/30/2011
@Sam:并不意味着“文件位置在末尾,下次读取将失败”。这意味着“您尝试读取文件末尾以外的内容,但失败了”eof()
1赞 Erik 4/30/2011
@Sam:关键是,在循环中,直到文件结束你开始阅读。您一直阅读到文件末尾,然后再读一遍。而且您没有测试读取可能失败的其他方式。while (!eof()) { cin >> foo; }
7赞 Erik 4/30/2011
@Sam: .这是一个典型的结构,它没有按照程序员的意图去做。它不会读取所有整数并再次显示它们,它最多会读取所有整数并显示它们,然后再次显示最后一个整数。如果你给它,例如“1 2 abc”作为输入,它将读取并显示“1”、“2”,然后永远循环显示“2”。int foo; while (!cin.eof()) { cin >> foo; cout << foo << "\n" }
1赞 Tronic 1/21/2013
@Portablejim不幸的是,你的教授错了,那根本无济于事。无论你如何编写循环条件,它都不起作用。它有时会创建额外的圆角,或者会省略最后一个有效值。eof() 为 false 并不能保证下一次读取会成功(第一个谬误)。即使在成功读取后,eof() 也可能为真(第二个谬误)。
12赞 Puppy 4/30/2011 #2

你不应该使用它,因为如果输入由于其他原因失败,你可能会被搞砸。

while(!file.eof()) {
    int i;
    file >> i;
    doSomething(i);
}

如果文件的内容是“WHAARRRRRRGARBL”,在上面的循环中会发生什么?它无限循环,因为它不是文件的末尾,但你仍然无法从中提取 int。

评论

0赞 Sam 4/30/2011
只是大声思考,但你不能把它放在一根绳子里然后操纵它吗?还是效率低下?
0赞 Drise 8/2/2012
效率低下,使用格式化输入有什么意义?cin >> somedouble >> someint >> somechar;
4赞 David Thornley 4/30/2011 #3

你如何使用它?会告诉你的是,流已经到达了文件的末尾,它试图读取不存在的数据。.eof()

这通常不是你想要的。通常,您想知道您正在点击文件末尾,或者您即将点击文件末尾,而不是您已经点击了它。在一个循环中,例如:

while(!f.eof())
{
    f >> /* something */;
    /* do stuff */
}

您将尝试读取输入并失败,然后您将执行 中的所有内容,然后循环条件失败并且循环停止。/* do stuff */

该循环的另一个问题是输入可能以其他方式失败。如果文件上存在非 EOF 的错误条件,则将返回但不会。.fail()true.eof()

评论

0赞 Sam 4/30/2011
所以你是说这是因为我的变量或我选择保存数据的任何内容都不适合这种类型吗?我不确定为什么这对我来说如此令人困惑。
0赞 David Thornley 4/30/2011
@Sam:读取错误的数据是可能的,但你必须单独处理。它不会触发该函数或任何其他类似函数。但是,如果读取文件时出现系统错误,您可能还想停止。.eof()
3赞 Lee Louviere 7/22/2011 #4

如果上述答案令人困惑:

人们认为它所做的是错误的:

  • eof() 不会查看您读取的最后一部分是否包含文件的最后一个字节。
  • 它不会查看下一个字节是否在文件末尾之后。

它的实际作用:

  • eof() 报告上次读取是否包含超过文件末尾的字节。

如果 eof() 为 true,则您已经犯了一个错误。教授们这样解释。使用它意味着什么,发生了错误。

评论

0赞 Tronic 1/21/2013
读取文件末尾不是错误,而是一个非常正常的操作。例如,考虑 istringstream s(“123”);int i;第>> i;现在 s.eof() 为 true(因为如果有第四位数字,则必须查看读取),s.fail() 为 false(因为读取成功),i 包含值 123。