These two files are identical up to first oef, but are different after first oef.
1 2
line 1
eof
1 2 3
line 1
line 2
eof
The following code wants to compare two files, one line at a time.
But there is a syntax error in the do-while condition (on last line of code):
1 2 3 4 5 6 7
$ g++ compareFiles.cpp
compareFiles.cpp: In function ‘int main()’:
compareFiles.cpp:61:32: error: cannot convert ‘std::ifstream {aka std::basic_ifstream<char>}’ to ‘FILE* {aka _IO_FILE*}’ for argument ‘1’ to ‘int feof(FILE*)’
} while ( !feof(if_expected) && !feof(if_result) ); //until one file reaches end
^
compareFiles.cpp:61:52: error: cannot convert ‘std::ifstream {aka std::basic_ifstream<char>}’ to ‘FILE* {aka _IO_FILE*}’ for argument ‘1’ to ‘int feof(FILE*)’
} while ( !feof(if_expected) && !feof(if_result) ); //until one file reaches end
But putting the getline() in the conditional causes the while loop to exit before "line 2" is compared to "eof"
The end-of-file marker is not a line; it doesn't make sense to compare a line to it.
In other words, if you try to read past the end-of-file, the read fails. What do you expect as the result of a failed read?
From http://www.cplusplus.com/reference/string/string/getline/ istream& getline (istream& is, string& str);
getline() returns reference to input istream&.
If the appropriate flag has been set with is's member function ios::exceptions, an exception of type ios_base::failure is thrown.
If both lines are "fail" (because eof) then the files are equal.
If one getline returns a string (line) and the other "fail" (eof), then the files are not equal. if (line_result != line_expected) //compare lines
What do you expect as the result of a failed read?
Sorry, I should have been more precise: after std::getline(stream, line)
returns a stream with its eofbit high, what do you expect line to contain?
To answer the question: line will contain all the stuff extracted before the EOF was reached (perhaps a blank line, if the file ends with a trailing newline.) This can very well coincide with the contents of lines in the other file.
If one getline returns a string (line) and the other "fail" (eof), then the files are not equal.
As you say -- if exactly one stream has failed thanks to eofbit being set, the files are different. Comparing the strings you pass in to the getline() calls after a stream failure isn't sufficient.
bool are_identical( std::istream& a, std::istream& b )
{
std::string one, two ;
while( std::getline( a, one ) && std::getline( b, two ) )
if( one != two ) returnfalse ; // lines don't compare equal, return false
// if a is not in a failed/eof state, then b must be in a failed/eof state
if(a) returnfalse ;
else // if a is in a failed/eof state (nothing more could be read from a)
return !std::getline( b, two ) ; // return true if nothing more can be read from b
}