【问题标题】:eof() bad practice? [duplicate]eof() 不好的做法? [复制]
【发布时间】:2011-08-15 19:26:07
【问题描述】:

可能重复:
Why is iostream::eof inside a loop condition considered wrong?

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

【问题讨论】:

  • 我认为您是指feof() 函数?
  • 他可能是指 iostream::eof() 之一。

标签: c++ eof


【解决方案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";
  }
}

【讨论】:

  • 但是如果你已经读到文件末尾了,不应该没有剩余信息吗?
  • @Sam: eof() 并不意味着“文件位置已结束,下一次读取将失败”。这意味着“您试图读取文件超出文件结尾的内容,但失败了”
  • 我想我明白你在说什么,但是阅读超过文件末尾会带来什么危害?你不会仍然提取所有数据吗?还是您有时说您不想要所有数据?或者..
  • @Sam:关键是在while (!eof()) { cin &gt;&gt; foo; } 循环中,您不会读取直到文件结尾。您正在阅读直到文件结束再一次。而且您没有测试读取可能失败的其他方式。
  • @Sam:int foo; while (!cin.eof()) { cin &gt;&gt; foo; cout &lt;&lt; foo &lt;&lt; "\n" }。这是一个典型的构造,它不符合程序员的意图。它不会读取所有整数并再次显示它们,它会充其量读取所有整数并显示它们,然后再次显示最后一个整数。如果你给它,例如“1 2 abc”作为输入,它会读取并显示“1”、“2”,然后一直循环显示“2”。
【解决方案2】:

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

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

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

【讨论】:

  • 只是一种大声思考,但你不能把它放在一个字符串中然后操纵它吗?还是只是效率低下?
  • 效率低下,使用像cin &gt;&gt; somedouble &gt;&gt; someint &gt;&gt; somechar;这样的格式化输入有什么意义?
【解决方案3】:

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

这通常不是您想要的。通常,您想知道您正在到达文件末尾,或者您即将到达文件末尾,而不是您已经到达它。在这样的循环中:

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

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

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

【讨论】:

  • 所以你是说这是因为我的变量或我选择保存数据的任何东西不适合那种类型吗?我不知道为什么这让我感到如此困惑。
  • @Sam:可能会读取错误的数据,但您必须单独处理。它不会触发.eof() 函数或任何其他类似函数。但是,如果在读取文件时出现系统错误,您可能也想停止。
【解决方案4】:

如果上述答案令人困惑:

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

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

它实际上做了什么:

  • eof() 报告最后一次读取是否包含文件末尾之后的字节。

如果 eof() 为真,那么你已经犯了一个错误。从而解释了教授的说法。使用它的意思,发生了错误。

【讨论】:

  • 读取文件末尾不是错误,而是非常正常的操作。考虑例如字符串流 s("123");诠释我; s >> 我;现在 s.eof() 为真(因为如果有第四个数字,阅读必须偷看),s.fail() 为假(因为读取成功)并且 i 包含值 123。
猜你喜欢
  • 2012-08-06
  • 1970-01-01
  • 2012-03-02
  • 2023-03-30
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 2016-09-19
相关资源
最近更新 更多