3
bool ios::eof ( ) const;

According to the library,

The function returns true if the eofbit stream's error flag has been set by a previous i/o operation. This flag is set by all standard input operations when the End Of File is reached in the sequence associated with the stream.

I wrote a program to run some tests:

int main(int argc, char *argv[])
{
    ifstream ifs(argv[1]);
    float f;
    ifs >> f;

    cout << ifs.eof() << endl; //check if eofbit set

    ifs.close();
}

I tested 2 files, testcase1.txt and testcase2.txt.

testcase1.txt was generated in the terminal with cat, [Ctrl-D] was used to end input:

[~/C++ $] cat > testcase1.txt
1.234[Ctrl-D]

testcase2.txt was generated in vim, I opened up vim and just inputted 1.234, and then saved and exited.

Test Result

Test result with testcase1.txt is 1, which means the eofbit is set,

[~/C++ $] ./a.out testcase1.txt
1

Test result with testcase2.txt is 0,

[~/C++ $] ./a.out testcase2.txt
0

I open both testcase1.txt and testcase2.txt in vim, they look exactly the same, then why the eofbit wasn't set for testcase2.txt?

Alcott
  • 17,905
  • 32
  • 116
  • 173
  • 2
    Could it be that vim appended a newline? – Björn Pollex Jan 11 '12 at 07:38
  • @Alcott: they may look the same but be slightly different. You could check with an hexadecimal editor for example whether their content is exactly identical... chances are they are not. – Matthieu M. Jan 11 '12 at 07:39
  • @BjörnPollex, I open both files in `vim`, they all are one line in there, look like no `newline` or `whitespace` appended, just `1.234`. – Alcott Jan 11 '12 at 07:44
  • @Alcott, the "new line" is a end-of-line marker. You have NL even if you got one line. Try `xxd your_file`, you see the `0a` bit is the new line. – J-16 SDiZ Jan 11 '12 at 07:58
  • @Alcott you can look at your files with a hex editor if you want to see exactly what bytes they contain. Also, a file with a newline at the end would have a greater file size, so `ls` will also tell you they're not equal. – Mr Lister Jan 11 '12 at 08:05
  • @J-16SDiZ, yes, there is `0a`, is it appended automatically by vim for each line? – Alcott Jan 11 '12 at 08:05

2 Answers2

3

As you see in comment, there is a new line:

ifstream ifs(argv[1]);
float f;
ifs >> f;
char c;
ifs.get( c ); // this will get '\n'

Even so, the EOF still won't set.... Read the paragraph you quoted again:

The function returns true if the eofbit stream's error flag has been set by a previous i/o operation. This flag is set by all standard input operations when the End Of File is reached in the sequence associated with the stream.

To get the eof bit set, you have to read PASS the eof. You can use peek() to do it if you want.

ifstream ifs(argv[1]);
float f;
ifs >> f;
char c;
ifs.get( c ); // this will get '\n'
ifs.eof();  // this is false;
ifs.peek();
ifs.eof(); // this is true

See also: istream::peek curious behavior wrt. EOF

Community
  • 1
  • 1
J-16 SDiZ
  • 26,473
  • 4
  • 65
  • 84
2

The vim is going to add a new line at the end of the file. That is why EOF is not reached.

BЈовић
  • 62,405
  • 41
  • 173
  • 273
  • a newline appended? Does it mean, if I `:set nu`, it should be `2` lines in there? – Alcott Jan 11 '12 at 07:47
  • @Alcott no, that means that the EOF is in the next line (not in the line where the number is) – BЈовић Jan 11 '12 at 08:01
  • @Alcott, no. it means you have "set endofline" in vim (default is on). This append a NL at the end of file. Do a `:help eol` – J-16 SDiZ Jan 11 '12 at 08:04
  • @Alcott: Actually, as far as I understand the Unix convention for text files is that every line has to end with a newline character. That is, a file that doesn't end with `\n` technically isn't a valid text file. Since the `\n` is part of the line it ends, it doesn't increase the line count. Rather, `testcase1.txt` is technically incorrect. I also just tested with `wc`, and it reports *zero* lines if no newline character is present. – celtschk Jan 11 '12 at 08:09