Reputation: 189
I'm having a strange issue where printing to the console using rdbuf() from a file using ifstream works, but the string parameter inside of getline never returns a value, and thus fails to print to the console in a for loop. I was trying to add the lines in the file to a vector for processing and I know there's other methods to do that, but I'm confused as to why the getline would fail. The file consists of the following text:
One
Two
Three
Four
Code below.
std::string path = "C:/testfile.txt";
std::ifstream File(path);
File.open(path);
std::string placeholder;
if (!File.is_open())
{
std::cout << "WARNING: Unable to open file" << std::endl;
}
else
{
//This prints to the console correctly;
std::filebuf* stream = File.rdbuf();
std::cout << stream << std::endl;
//------------------------------------
//This fails because placeholder is always "" and the loop doesn't run.
for (std::string output; std::getline(File, placeholder);)
{
std::cout << output << std::endl;
}
File.close();
}
Upvotes: 0
Views: 222
Reputation: 409356
File.rdbuf()
doesn't return a copy of the buffer for the stream, it returns a pointer to the actual in-use buffer for the stream.
That means when you do
std::cout << stream << std::endl;
you exhaust the actual file stream, and put it at the end of file. Which means the std::getline
call will fail.
You need to reset the stream and seek back to the beginning again after the output.
The problem with opening the file twice is that the second attempt will fail, meaning that failbit
will be set. And that means all future operations on the stream itself (but not the buffer) will fail.
See e.g. this open
reference for details.
The obvious solution is of course to not open the file twice, but if there's a risk that it might happen then always clear
the stream status after calling open
.
Upvotes: 3