I’ve seen at least two ways of reading lines from a file in C++ tutorials:
std::ifstream fs("myfile.txt");
if (fs.is_open()) {
while (fs.good()) {
std::string line;
std::getline(fs, line);
// ...
and:
std::ifstream fs("myfile.txt");
std::string line;
while (std::getline(fs, line)) {
// ...
Of course, I can add a few checks to make sure that the file exists and is opened. Other than the exception handling, is there a reason to prefer the more-verbose first pattern? What’s your standard practice?
This is not only correct but preferable also because it is idiomatic.
I assume in the first case, you’re not checking
fsafterstd::getline()asif(!fs) break;or something equivalent. Because if you don’t do so, then the first case is completely wrong. Or if you do that, then second one is still preferable as its more concise and clear in logic.The function
good()should be used after you made an attempt to read from the stream; its used to check if the attempt was successful. In your first case, you don’t do so. Afterstd::getline(), you assume that the read was successful, without even checking whatfs.good()returns. Also, you seem to assume that iffs.good()returns true,std::getlinewould successfully read a line from the stream. You’re going exactly in the opposite direction: the fact is that, ifstd::getlinesuccessfully reads a line from the stream, thenfs.good()would returntrue.The documentation at cplusplus says about
good()that,That is, when you attempt to read data from an input stream, and if the attempt was failure, only then a failure flag is set and
good()returnsfalseas an indication of the failure.If you want to limit the scope of
linevariable to inside the loop only, then you can write aforloop as:Note: this solution came to my mind after reading @john’s solution, but I think its better than his version.
Read a detail explanation here why the second one is preferable and idiomatic:
Or read this nicely written blog by @Jerry Coffin: