#include <iostream>
#include <sstream>
#include <limits>
#include <cassert>
struct X { int a_, b_; };
std::istream& operator>>(std::istream& is, X& x)
{
char c;
if (is >> x.a_ && is.get(c))
if (c == '\n')
{
x.b_ = 1;
return is;
}
else if (c == '/' && is >> x.b_)
return is;
else
is.setstate(std::istream::failbit);
return is;
}
int main()
{
std::istringstream iss("5\n10/2\n3xyz\n8/17\n9\nNOWAY\n42/4\n");
X x;
while (iss >> x)
std::cout << "parsed " << x.a_ << '/' << x.b_ << '\n';
iss.clear();
std::string remnants;
assert(getline(iss, remnants));
std::cout << "parsing failed, line remnants for '" << remnants << "'\n";
// normally would prefer following to getline above...
// iss.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
iss.exceptions(std::istream::failbit);
while (iss)
try
{
while (iss >> x)
std::cout << "also parsed " << x.a_ << '/' << x.b_ << '\n';
}
catch (const std::exception& e)
{
std::cout << "caught exception " << e.what() << '\n';
if (!iss.eof())
{
iss.clear();
iss.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
std::cout << "eof " << iss.eof() << ", bad " << iss.bad()
<< ", fail " << iss.fail() << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPGxpbWl0cz4KI2luY2x1ZGUgPGNhc3NlcnQ+CgpzdHJ1Y3QgWCB7IGludCBhXywgYl87IH07CgpzdGQ6OmlzdHJlYW0mIG9wZXJhdG9yPj4oc3RkOjppc3RyZWFtJiBpcywgWCYgeCkKewoJY2hhciBjOwoJaWYgKGlzID4+IHguYV8gJiYgaXMuZ2V0KGMpKQoJICAgIGlmIChjID09ICdcbicpCgkgICAgewoJICAgIAl4LmJfID0gMTsKCSAgICAgICAgcmV0dXJuIGlzOwoJICAgIH0KCSAgICBlbHNlIGlmIChjID09ICcvJyAmJiBpcyA+PiB4LmJfKQoJICAgICAgICByZXR1cm4gaXM7CgkgICAgZWxzZQoJICAgICAgICBpcy5zZXRzdGF0ZShzdGQ6OmlzdHJlYW06OmZhaWxiaXQpOwoJcmV0dXJuIGlzOwp9CgppbnQgbWFpbigpCnsKCXN0ZDo6aXN0cmluZ3N0cmVhbSBpc3MoIjVcbjEwLzJcbjN4eXpcbjgvMTdcbjlcbk5PV0FZXG40Mi80XG4iKTsKCVggeDsKCXdoaWxlIChpc3MgPj4geCkKCSAgICBzdGQ6OmNvdXQgPDwgInBhcnNlZCAiIDw8IHguYV8gPDwgJy8nIDw8IHguYl8gPDwgJ1xuJzsKCWlzcy5jbGVhcigpOwoJCglzdGQ6OnN0cmluZyByZW1uYW50czsKCWFzc2VydChnZXRsaW5lKGlzcywgcmVtbmFudHMpKTsKCXN0ZDo6Y291dCA8PCAicGFyc2luZyBmYWlsZWQsIGxpbmUgcmVtbmFudHMgZm9yICciIDw8IHJlbW5hbnRzIDw8ICInXG4iOwoJLy8gbm9ybWFsbHkgd291bGQgcHJlZmVyIGZvbGxvd2luZyB0byBnZXRsaW5lIGFib3ZlLi4uCgkvLyBpc3MuaWdub3JlKHN0ZDo6bnVtZXJpY19saW1pdHM8c3RkOjpzdHJlYW1zaXplPjo6bWF4KCksICdcbicpOwoJCglpc3MuZXhjZXB0aW9ucyhzdGQ6OmlzdHJlYW06OmZhaWxiaXQpOwoJd2hpbGUgKGlzcykKCSAgICB0cnkKCSAgICB7CiAgICAgICAgCXdoaWxlIChpc3MgPj4geCkKCSAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiYWxzbyBwYXJzZWQgIiA8PCB4LmFfIDw8ICcvJyA8PCB4LmJfIDw8ICdcbic7CgkgICAgfQoJICAgIGNhdGNoIChjb25zdCBzdGQ6OmV4Y2VwdGlvbiYgZSkKCSAgICB7CgkgICAgCXN0ZDo6Y291dCA8PCAiY2F1Z2h0IGV4Y2VwdGlvbiAiIDw8IGUud2hhdCgpIDw8ICdcbic7CgkgICAgCWlmICghaXNzLmVvZigpKQoJICAgIAl7CgkgICAgCSAgICBpc3MuY2xlYXIoKTsKCSAgICAgICAgICAgIGlzcy5pZ25vcmUoc3RkOjpudW1lcmljX2xpbWl0czxzdGQ6OnN0cmVhbXNpemU+OjptYXgoKSwgJ1xuJyk7CgkgICAgCX0KCSAgICB9CglzdGQ6OmNvdXQgPDwgImVvZiAiIDw8IGlzcy5lb2YoKSA8PCAiLCBiYWQgIiA8PCBpc3MuYmFkKCkKCSAgICAgPDwgIiwgZmFpbCAiIDw8IGlzcy5mYWlsKCkgPDwgJ1xuJzsKfQ==