getline() sets failbit and skips last line
- by Thanatos
I'm using std::getline() to enumerate through the lines in a file, and it's mostly working. It's left me curious however - std::getline() is skipping the very last line in my file, but only if it's blank. Using this minimal example:
#include <iostream>
#include <string>
int main()
{
std::string line;
while(std::getline(std::cin, line))
std::cout << "Line: “" << line << "”\n";
return 0;
}
If I feed it this:
Line A
Line B
Line C
I get those lines back at me. But this:
Line A
Line B
Line C
[* line is present but blank, ie, the file end is: "...B\nLine C\n" *]
(I unfortunately can't have a blank line in SO's little code box thing...)
So, first file has three lines ( ["Line A", "Line B", "Line C"] ), second file has four ( ["Line A", "Line B", "Line C", ""] )
This to me seems wrong - I have a four line file, and enumerating it with getline() leaves me with 3. What's really got me scratching my head is that this is exactly what the standard says it should do. (21.3.7.9)
Even Python has similar behaviour (but it gives me the newlines too - C++ chops them off.) Is this some weird thing where C++ is expected lines to be terminated, and not separated by '\n', and I'm feeding it differently?
Edit
Clearly, I need to expand a bit here. I've met up with two philosophies of determining what a "line" in a file is:
Lines are terminated by newlines - Dominant in systems such as Linux, and editors like vim. Possible to have a slightly "odd" file by not having a final '\n' (a "noeol" in vim). Impossible to have a blank line at the end of a file.
Lines are separated by newlines - Dominant in just about every Windows editor I've ever come across. Every file is valid, and it's possible to have the last line be blank.
Of course, YMMV as to what a newline is.
I've always treated these as two completely different schools of thought. One earlier point I tried to make was to ask if the C++ standard was explicitly or merely implicitly following the first.
(Curiously, where is Mac? terminated or separated?)