I have this issue where my custom overloaded >> operator always evaluates as 'false' when I check for success. I think it may have to do with the fact that my istream is infact a redirected ifstream (meaning I passed an ifsteam to the isteam), though I'm unsure how to solve it.
Here's the code snippet, simplified as much as it can be:
#include <istream>
#include <string>
#include <fstream>
#include <iostream>
class SomeClass {
public:
SomeClass() = default;
friend std::istream& operator>>(std::istream& is, SomeClass& random);
private:
std::string my_str;
};
std::istream& operator>>(std::istream& is, SomeClass& random) {
while(std::getline(is, random.my_str));
if (random.my_str != "Hello World") {
is.setstate(std::ios::failbit);
return is;
}
is.setstate(std::ios::goodbit); //I didn't have this here before, put it in as a test
return is;
}
bool io_parser(std::istream& input_stream) {
SomeClass random;
if (!(input_stream >> random))
return false;
return true;
}
int main(int argc, char* argv[]) {
std::cout << argc << std::endl;
std::istream* input_stream;
std::ifstream input_file(argv[1]);
if (!input_file.is_open()) {
std::cout << "File failed to open." << std::endl;
return EXIT_FAILURE;
}
input_stream = &input_file;
std::cout << io_parser(*input_stream) << std::endl;
return EXIT_SUCCESS;
}
Sample input:
Hello World
Hello World
Hello World
No matter what, it won't work as long as the std::getline() is in a while(). If it's alone, it works.
You have a couple of issues.
while(std::getline(is, random.my_str));
will always keep reading and discarding lines until it encounters an error. This may be what you intended but seems odd? After this loop the stream will be in a failed state (normally with eof
set).
is.setstate(std::ios::failbit);
correctly sets the fail
bit. However
is.setstate(std::ios::goodbit);
is not the way to return the stream to a good
state. setstate
adds the flag you specify to the current stream state, as goodbit
is actually 0
, setstate(std::ios::goodbit)
has no effect on the stream state. To set the stream state you need to call clear
:
is.clear(std::ios::goodbit);
or for setting std::ios::goodbit
you can just call with no arguments:
is.clear();