the following code is not behaving like I would expect. Please help me understand how it works.
#include <algorithm>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
struct user
{
string name;
string age;
string id;
};
istream& operator>>(istream& is, user& s)
{
getline(is, s.name, ':');
getline(is, s.age, ':');
getline(is, s.id);
return is;
}
int main(int argc, char* argv[])
{
ifstream file("file.txt");
vector<user> vec;
copy(istream_iterator<user>(file), istream_iterator<user>(), back_inserter(vec));
return 0;
}
My custom operator>> is called twice but I would expect it to be called only once because the contents are:
John:forty:21-5821-0
In general, to read in an entire file, you read until a read fails. Then you know either something went wrong, or you got them all. Either way, you can't know you reached the end of the file until you fail to read. Since the first one succeeds, it must try a second time, to find out if there is a second element. The psudocode for this is
while(in_stream >> object) {
myvector.push_back(object);
}
Also note that this is the "idiomatic" way to read in an entire file of values. If you're checking for eof
, fail
, or bad
, you're code is probably wrong.
That said, your istream& operator>>(istream& is, user& s)
function is just fine. The second time it is called, the first getline
will fail, setting the stream to a bad state (eof), the next two getline
s will fail as well, and it will return the stream, and everything works perfectly. Just remember that any or all of those variables may hold complete nonsense, since the read failed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With