So given the definitions:
typedef char Task;
struct Tache {
char step;
int duration;
list<Task> precedentTask;
};
I've written an extraction operator for 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 I try to use this extraction operator with an istream_iterator
the precedentTask
member seems to bleed into the next element. For 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>() };
for (const auto& i : allTaches) {
cout << i.step << ' ' << i.duration << ' ';
copy(cbegin(i.precedentTask), cend(i.precedentTask), ostream_iterator<Task>(cout, " "));
cout << endl;
}
I am getting:
A 3
B 4 A
C 2 A A
E 5 A A A
G 3 A A A A
J 8 A A A A B H
H 7 A A A A B H C E G
I 6 A A A A B H C E G G
F 5 A A A A B H C E G G H
Rather than my expected:
A 3
B 4 A
C 2 A
E 5 A
G 3 A
J 8 B H
H 7 C E G
I 6 G
F 5 H
Am I misusing the sregex_token_iterator
?
This has nothing to do with regex and everything to do with what
istream_iterator
does under the hood: it only has oneT
element that it will read into when you increment it:Your stream operator is just appending to
rhs.precedentTask
, but it's not necessarily empty to start with. Just clear it first. This isn't anistream_iterator
problem either, youroperator>>
has to be able to work in this situation too:If all you're doing is appending, then every subsequent
Tache
after the first one will be wrong. You are completely responsible for initializing all of the members of the object and you should make no assumptions about their previous values.I'd recommend substituting
transform()
for just a loop:or wrapping that in a range: