In the following code I do a read from a file containing simply "12345" using std::getline, and immediately after attempt to write "67890" to the file. This write will fail unless I first call myfile.clear(). Why is this? What exactly is breaking? Is there a way to still use std::getline in a loop but prevent an error from occurring when the last line is read? What is correct?
#include <fstream>
#include <iostream>
#include <string>
using std::cout;
using std::fstream;
using std::string;
void printStats(fstream&);
int main(int argc, char* argv[])
{
// textfile.txt:
// 1234
fstream myfile("textfile.txt", std::fstream::in | std::fstream::out);
string line;
cout << "\n"
<< "Before reading lines in a loop.\n";
printStats(myfile);
cout << "\n"
<< "Reading lines in the loop.\n";
while (myfile.eof() != true)
{
std::getline(myfile, line); // Last call here causes EOF and FAIL bit to be set
cout << "line=" << line << "\n";
}
cout << "\n"
<< "After reading lines in a loop.\n";
printStats(myfile);
myfile.clear(); // If I comment this out the write below fails
myfile << "67890\n";
myfile.close();
return 0;
}
void printStats(fstream& fileStream)
{
int position = fileStream.tellp();
cout << "position = " << position << "\n";
if (fileStream.eof() == true)
cout << "EOF bit = 1\n";
else
cout << "EOF bit = 0\n";
if (fileStream.fail() == true)
cout << "FAIL bit = 1\n";
else
cout << "FAIL bit = 0\n";
if (fileStream.bad() == true)
cout << "BAD bit = 1\n";
else
cout << "BAD bit = 0\n";
}
Here are the results from execution with myfile.clear() commented out:
user@Ubuntu:~/example/test$ cat textfile.txt ; ./test ; cat textfile.txt
12345
Before reading lines in a loop.
position = 0
EOF bit = 0
FAIL bit = 0
BAD bit = 0
Reading lines in the loop.
line=12345
line=
After reading lines in a loop.
position = -1
EOF bit = 1
FAIL bit = 1
BAD bit = 0
12345
Here are the results from execution with myfile.clear() included in the code:
user@Ubuntu:~/example/test$ cat textfile.txt ; ./test ; cat textfile.txt
12345
Before reading lines in a loop.
position = 0
EOF bit = 0
FAIL bit = 0
BAD bit = 0
Reading lines in the loop.
line=12345
line=
After reading lines in a loop.
position = -1
EOF bit = 1
FAIL bit = 1
BAD bit = 0
12345
67890
This is compiled with g++ on Ubuntu Linux 20.04
user@Ubuntu:~/example/test$ /usr/bin/g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I did find this similar result below but it does not clearly explain the answers to my questions.
c++ getline() looping when used in file with a read in int array?