C++ .eof() 循环不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8734116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
.eof() loop not working
提问by Sean
I'm trying to read in numbers from a file and putting them into an array. Right now when I run the program it prints 8 numbers, then the line ends and prints the same 8 numbers. It's in a never ending loop. What am I doing wrong?
我正在尝试从文件中读取数字并将它们放入数组中。现在,当我运行该程序时,它会打印 8 个数字,然后该行结束并打印相同的 8 个数字。这是一个永无止境的循环。我究竟做错了什么?
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int num;
ifstream infile;
infile.open("euler8Nums.txt");
infile >> num;//must attempt to read info prior to an eof() test
while(!infile.eof()){
cout << num << endl;
infile >> num;
}
infile.close();
return 0;
}
回答by Mooing Duck
In general, don't use .eof()
or .bad()
. Just check the state of the stream itself
一般来说,不要使用.eof()
或.bad()
。只需检查流本身的状态
while (infile >> num)
cout << num << endl;
The eof flag will not be set if the stream fails to parse an input, and then the stream will cease to operate until the state is cleared. If you checked bad
instead, it would go until it failed to parse, but would bug out at the EOF. So just check if the stream is still .good()
, (which is implicit when it's in a while loop).
如果流无法解析输入,则不会设置 eof 标志,然后流将停止运行,直到状态被清除。如果您bad
改为检查,它将一直持续到解析失败,但会在 EOF 处出错。所以只需检查流是否仍然.good()
, (当它处于 while 循环时是隐式的)。
In your case, it's an infinite loop because the file did not openand then you are attempting to read numbers, but the reading is doing nothingbecause the file isn't open. Thus it never reads the eof
, thus infinite loop.
在您的情况下,这是一个无限循环,因为文件没有打开,然后您正在尝试读取数字,但是由于文件未打开,读取没有任何作用。因此它永远不会读取eof
,从而无限循环。
回答by Dietmar Kühl
I don't know what your file contains or how it would cause an infinite loop printing more than the last number. However, the eof()
bit is only good for error reporting but not
for loop control. Also, there is a lot of other stuff in the code which is utterly unnecessary. The following program should read the numbers OK:
我不知道你的文件包含什么或者它如何导致无限循环打印超过最后一个数字。但是,该eof()
位仅适用于错误报告,但not
适用于循环控制。此外,代码中还有很多其他的东西是完全没有必要的。以下程序应该可以正确读取数字:
#include <iostream>
#include <fstream>
int main()
{
std::ifstream infile("euler8Nums.txt");
for (int num; infile >> num; )
std::cout << num << "\n";
return 0;
}
I never saw a point in calling open()
separately unless there is a conditional necessary necessary before the file name can be worked out. Likewise, calling close()
explicitly seems to be pretty pointless unless you want to check that the close was successful (although I'm unsure if close()
on an input stream has an opportunity to fail).
我从来没有看到open()
单独调用的意义,除非在计算文件名之前有必要的条件。同样,close()
除非您想检查关闭是否成功(尽管我不确定close()
输入流是否有机会失败),否则显式调用似乎毫无意义。
Another of my pet peeves is the unnecessary use of std::endl
: this manipulator is a relatively frequent source of bad performance! It does two things:
我的另一个烦恼是不必要地使用std::endl
:这个操纵器是性能不佳的一个相对频繁的来源!它做两件事:
- It writes an end of line character, i.e.
\n
(or, on wide character streams the result of widening this character). - It flushes the stream. On file streams this is a rather expensive operation which can easily slow down be a substantial factor (not just a few percent). The actual writes often dominate the actual real-time performances of code writing a data to a file.
- 它写一个行尾字符,即
\n
(或者,在宽字符流上加宽这个字符的结果)。 - 它冲洗流。在文件流上,这是一项相当昂贵的操作,很容易减慢速度,这是一个重要因素(不仅仅是几个百分点)。实际写入通常支配将数据写入文件的代码的实际实时性能。
Only flush the stream when you really mean to. If you feel that you need extra flushes on your stream, e.g. when trying to find what is written right before a crash, just set std::unitbuf
on the stream object: this will be worse from a performance point of view because it flushes the stream after each insertion but it is easily removed once the problem is located.
仅在您真正想要的时候刷新流。如果你觉得你的流需要额外的刷新,例如当试图找到崩溃前写入的内容时,只需std::unitbuf
在流对象上设置:从性能的角度来看这会更糟,因为它在每次插入后刷新流但是一旦找到问题,就很容易将其删除。
Of course, the resulting program can be changed to something even neater like
当然,生成的程序可以更改为更简洁的内容,例如
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
int main()
{
std::copy(std::istream_iterator<int>(std::ifstream("euler8Nums.txt") >> std::ws),
std::istream_iterator<int>(), std::ostream_iterator<int>(std::cout, "\n"));
}