so given definitions:
typedef char task; struct tache { char step; int duration; list<task> precedenttask; };
i've written extraction operator tache
:
istream& operator>>(istream& lhs, tache& rhs) { string line; getline(lhs, line, '\n'); stringstream ss(line); ss >> rhs.step; ss.ignore(numeric_limits<streamsize>::max(), '('); ss >> rhs.duration; ss.ignore(numeric_limits<streamsize>::max(), ')'); const regex re("\\s*,\\s*([a-za-z])"); string precedenttasks; getline(ss, precedenttasks); transform(sregex_token_iterator(cbegin(precedenttasks), cend(precedenttasks), re, 1), sregex_token_iterator(), back_insert_iterator<list<task>>(rhs.precedenttask), [](const string& i) { return i.front(); }); return lhs; }
however when try use extraction operator istream_iterator
precedenttask
member seems bleed next element. example, given:
stringstream seq("a(3)\nb(4),a\nc(2),a\ne(5),a\ng(3),a\nj(8),b,h\nh(7),c,e,g\ni(6),g\nf(5),h"); list<tache> alltaches{ istream_iterator<tache>(seq), istream_iterator<tache>() }; (const auto& : alltaches) { cout << i.step << ' ' << i.duration << ' '; copy(cbegin(i.precedenttask), cend(i.precedenttask), ostream_iterator<task>(cout, " ")); cout << endl; }
i getting:
a 3
b 4
c 2 a
e 5 a
g 3 a a
j 8 a a b h
h 7 a a b h c e g
6 a a b h c e g g
f 5 a a b h c e g g h
rather expected:
a 3
b 4
c 2
e 5
g 3
j 8 b h
h 7 c e g
6 g
f 5 h
am misusing sregex_token_iterator
?
this has nothing regex , istream_iterator
under hood: has 1 t
element read when increment it:
istream_iterator& operator++();
3 requires:in_stream != 0
.
4 effects:*in_stream >> value
.
5 returns:*this
.
your stream operator appending rhs.precedenttask
, it's not empty start with. clear first. isn't istream_iterator
problem either, operator>>
has able work in situation too:
tache foo; while (std::cin >> foo) { // ... }
if you're doing appending, every subsequent tache
after first 1 wrong. responsible initializing of members of object , should make no assumptions previous values.
i'd recommend substituting transform()
loop:
sregex_token_iterator it(cbegin(precedenttasks), cend(precedenttasks), re, 1), end; (; != end; ++it) { rhs.precedenttask.push_back(it->front()); }
or wrapping in range:
for (std::string match : sregex_matches(precedenttasks, re, 1)) { rhs.precedenttask.push_back(match.front()); }