I followed the deserialization procedure for the object using the stream operator <<. The procedure itself uses istreambuf_iterator<char>one by one to extract characters from the stream to build the object.
Ultimately, my goal is to be able to iterate through the stream with istream_iterator<MyObject>and insert each object into vector. Pretty standard, except that I can't get the istream_iteratoriteration to end when it hits the end of the stream. Right now, it just loops forever, although calls istream::tellg()indicate that I'm at the end of the file.
Here is the code to reproduce the problem:
struct Foo
{
Foo() { }
Foo(char a_, char b_) : a(a_), b(b_) { }
char a;
char b;
};
std::ostream& operator << (std::ostream& os, const Foo& f)
{
os << f.a << f.b;
return os;
}
std::istream& operator >> (std::istream& is, Foo& f)
{
if (is.good())
{
std::istreambuf_iterator<char> it(is);
std::istreambuf_iterator<char> end;
if (it != end) {
f.a = *it++;
f.b = *it++;
}
}
return is;
}
int main()
{
{
std::ofstream ofs("foo.txt");
ofs << Foo('a', 'b') << Foo('c', 'd');
}
std::ifstream ifs("foo.txt");
std::istream_iterator<Foo> it(ifs);
std::istream_iterator<Foo> end;
for (; it != end; ++it) cout << *it << endl;
}
, istreambuf_iterator, , , , .
, , istreambuf_iterator , EOF. istream::eof() false, istream::tellg() , istreambuf_iterator<char>(ifs) true istreambuf_iterator<char>(), , .
IOstreams, , , istream_iterator , , istream::operator void*() const true. istream :
return this->fail() ? 0 : const_cast<basic_ios*>(this);
, 0 (false), . istream_iterator, , .
, failbit std::istream& operator >> (std::istream& is, Foo& f), istreambuf_iterator true . . . , istream_iterator std::ios::failbit, " ". std::ios::eofbit? , failbit , , fstream - .
, istream::setstate(std::ios::failbit), ?