2

这是代码:

string fname = "/home/jack/example.csv";
ifstream csvin(fname.c_str());
if (csvin.eof()) {
    do_something;
}

我的问题是:在什么情况下eof()返回 true。我有以下选择:

  1. 文件不存在。
  2. 文件为空。
  3. 文件不存在或为空。

不幸的是,文档没有帮助,因为我不知道eofbit error state flag意味着什么。我也不明白什么End-of-File is reached in the sequence associated with the stream意思。我假设 c_str() 返回一些迭代器,如果它已经被某些东西使用它可能已经到达终点。但是,我对结果c_str()新鲜的简单情况感兴趣,如果文件不存在,它将返回什么,如果文件为空,它将返回什么?

已编辑

我只想知道上面给出的代码在两种情况下返回了什么:

  1. 文件不存在。
  2. 文件为空。
4

4 回答 4

4

当您在正在读取的流中的位置到达文件末尾时,eof()返回 true。它实际上返回读取文件末尾(试图读取过去)时设置的eof 标志的值。查看C++: .eof on an empty file以讨论 eof 和空文件!

于 2013-04-09T11:56:12.533 回答
2

eof如果设置了 eofbit 标志,则返回true(表示在 的情况下到达文件末尾ifstream)。

eofbit 标志可以由流上的所有输入操作(例如 a read)设置,当输入操作尝试读取超过流的末尾时(iow :到达流的末尾)。正如评论中所指出的,即使从概念上讲,只要读取最后一个字符(或不读取空流上的任何内容)就到达流的末尾,但流在尝试读取另一个字符之前并不知道这一点. 有关详细信息,请参阅每个输入操作的文档。

if请注意,构造流不是输入操作,因此在您展示的代码示例中,eofbit 在到达语句时不会设置。如果由于某种原因构造流失败(例如,文件不存在),则将设置失败位,可以使用fail.

编辑:看到您的编辑,我希望能更清楚地说明上述内容:

在您发布的代码中,if条件永远不会评估为真,因为ifstream构造函数没有设置 eofbit。

在文件不存在的情况下,将设置故障位,您可以像这样检查:

if (csvin.fail()) {
    // oops : failed to open the file for reading (file doesn't exist, or has the wrong permissions, or ...)
}

在文件为空的情况下,构造函数不会报错,但对流的第一个输入操作将设置 eofbit。在第一次输入操作之后,您可以检查eof是否到达文件末尾。

于 2013-04-09T12:00:38.963 回答
1

There's actually a small degree of implementation dependency as to when the eofbit is set. (The function eof() returns true if and only if the eofbit is set.) It is required to be set if, in the course of reading something (formatted or unformatted), a call to streambuf::sgetc() (or one of the other character getters) returns std::char_traits::eof(). It's not always clear when the implementation may look one character ahead—if it gets an end of file doing so, it sets eofbit; if it doesn't do the look-ahead, it doesn't.

I'm also unsure as to whether an implementation can set eofbit in cases where it knows that the next read must return eof, without actually having done the read; I'm fairly sure that existing implementations don't, however. (Do you really want the eofbit set when you seek to the end of file?) So in your example, you will almost surely never see eof() returning true.

All of this explains why you almost never do input.eof() (or input.good(), which includes the eofbit in its value as well). After trying to open the file, the usual condition is if ( input.is_open() ), although input.fail() can be used as well. When reading an already opened file, we test input.fail() after the attempted input, usually by using the stream object in a boolean context (i.e. if ( input ), or if ( !input )). After having detected failure, we may use eof() to determine whether the reason for failure was the end of file, or some other error (like "abc" when trying to input an int). Even then, it's not 100% infallible, and eof() may return true even if there was an error in the format. (Consider:

std::istringstream s( "1.3E+" );
double d;
s >> d;

In this case, s.eof() will almost certainly return true, dispite the fact that the input fails because of an error in the format, and not because of end of file.)

于 2013-04-09T13:07:47.547 回答
1

eof()true如果流上的最后一个操作试图读取文件的最后一个字节,则返回。请注意,它告诉您有关上一次操作成功的信息,而不是下一次操作成功的信息。许多代码示例都做出了错误的假设,即它告诉您有关下一个操作的一些信息,因此代码的行为不会像预期的那样。

于 2013-04-09T12:00:48.617 回答