问题
Here is the code:
string fname = "/home/jack/example.csv";
ifstream csvin(fname.c_str());
if (csvin.eof()) {
do_something;
}
My question is: In what case eof()
returns true. I have the following options:
- File does not exist.
- File is empty.
- File either does not exist or it is empty.
Unfortunately documentation does not help since I do not know eofbit error state flag
means. I also do not understand what End-of-File is reached in the sequence associated with the stream
mean. I assume that c_str() returns some iterator and if it is already used by something it might already reach its end. However, I am interested in simple case when result of c_str()
is fresh, what will it return if file does not exist and what will it return if file is empty?
EDITED
I just would like to know what the above given code returns in two cases:
- File does not exist.
- File is empty.
回答1:
eof() returns true when the position you are at in the stream you are reading from is has reached the end of the file. It actually returns the value of the eof flag that gets set when the end of the file has been read (attempted to read past). Check out C++: .eof on an empty file for a discussion on eof and empty files!
回答2:
eof
returns true
if the eofbit flag is set (indicating that the end of the file is reached in the case of an ifstream
).
The eofbit flag can be set by all input operations on the stream (eg. a read
) when the input operation tries to read past the end of the stream (iow : the end of the stream is reached). As pointed out in a comment, even though conceptually the end of the stream is reached as soon as the last character is read (or without reading anything on an empty stream), the stream doesn't know that until it tries to read another character. Refer to the documentation for each input operation for further details.
Note that constructing the stream is not an input operation, so in the code sample that you showed, the eofbit would not be set by the time it reaches the if
statement.
If constructing the stream fails for some reason (eg. a file that doesn't exist), then the failbit would be set, which can be checked with fail
.
EDIT: Seeing your edit, I'll state the above hopefully a bit more clearly :
In the code you posted, the if
condition would never evaluate to true, because the ifstream
constructor does not set the eofbit.
In the case the file doesn't exist, the failbit would be set, which you can check like so :
if (csvin.fail()) {
// oops : failed to open the file for reading (file doesn't exist, or has the wrong permissions, or ...)
}
In the case the file is empty, the constructor will not complain, but the very first input operation on the stream will set the eofbit. After that very first input operation, you can then check with eof
if the end of the file was reached or not.
回答3:
eof()
returns true
if the last operation on the stream attempted to read past the last byte of the file. Pay attention to the fact that it tells you something about the success of the last operation and not about the success of the next one. Many code samples makes the wrong assumption that it tells you something about the next operation and thus have code that will not behave as expected.
回答4:
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.)
来源:https://stackoverflow.com/questions/15901092/what-does-eof-returns