Verständnisproblem: istream_iterator
-
Hallo zusammen
Ich hab' hier grad ein kleines Problem mit folgendem Stück Code:
vector<string> woerter; istream_iterator<string> eos; istream_iterator<string> is(cin); cout << "iterator erstellt" << endl; copy(is, eos, back_inserter(woerter)); cout << "inhalt von iterator in vektor kopiert" << endl; copy(woerter.begin(),woerter.end(), ostream_iterator<string>(cout, ", "));Wenn ich das Programm laufen lasse, kann ich wie erwartet einen Text eingeben (da ich im Konstruktor des einten istream_iterators die Standardeingabe angebe) und das wird dann Wort für Wort in meinen Vektor kopiert.
Was ich aber nicht verstehe ist, dass ich nach der ersten Eingabe, noch mehr eingeben kann. Denn nach der ersten Eingabe kommt die erste Meldung, dass der Iterator erstellt wurde.
Ist danach die Standardeingabe also immernoch aktiv, bis ich sie durch CTRL+Z beende? Wieso bleibt das Programm nicht auf der Zeile mit cin im Konstruktor, bis ich die Eingabe beende?Oder läuft es folgendermassen:
im ersten Copy rufe ich ja den istream_iterator auf, den ich mit der Standardeingabe im Konstruktor erstellt habe. Dieser iterator und der eos sind nun solange ungleich, bis ich die Eingabe durch CTRL+Z beende. Durch jedes inkrementieren des ersten iterators (is), wird dessen Konstruktor erneut aufgerufen?Kurz und bündig:
Wieso erscheint die Ausgabe "iterator erstellt" und dennoch kann ich nachher noch mehr Text eingeben?Vielen Dank für allfällige Hilfe

-
Ein
istream_iteratorliest solange aus einem Stream, solange dieser gültig ist. Also muss der Stream ans Ende kommen (nicht das gleiche wie Zeilenende) oder eine ungültige Eingabe muss geschehen, was aber bei einer Worteingabe ziemlich schwierig ist
Wenn du nur eine Zeile willst, lies die Zeile zuerst in einenstd::stringmitstd::getline, dann erstelle einistringstreamund lies über diesen ein.Referenz: http://www.cplusplus.com/reference/
Grüssli
-
Okay, soweit klar.
Aber warum läuft's dann im Programmcode weiter, obwohl der Stream eigentlich noch am Lesen bzw. auf meine Eingabe am Warten ist?
-
Sobald du den
istream_iteratormit demstd::cinObjekt erstellst, wird zum ersten Mal ein Wert ausgelesen. Danach immer dann, wenn der Iterator inkrementiert wird.Steht alles hier:
http://www.cplusplus.com/reference/std/iterator/istream_iterator/Grüssli
-
Achso ok.
Hab das vorher mal gelesen aber ehrlichgesagt nicht ganz verstanden. Das passiert ja in operator++() (ohne Parameter ist's die preinkrement-Variante, richtig?) an folgender Stelle: *in_stream >> value, stimmt das?

Danke für deine Hilfe

Ich habe gerade noch eine kleine Frage bzgl. Call-by-Reference:
void kopiereWort(vector<string> &v, string wort) { v.push_back(wort); cout << "vector grösse: " << v.size() << ", wort: " << wort << endl; } vector<string> test; test.push_back("Dies"); test.push_back("ist"); test.push_back("ein"); test.push_back("Test"); vector<string> leererVector; for_each(test.begin(),test.end(), boost::bind(kopiereWort, leererVector, _1)); cout << "leererVector Grösse: " << leererVector.size() << endl;Nun müsste doch ganz am Ende der "leererVector" die 4 Elemente drin haben. In der Funktion kopiere Wort werden diese und die Grösse des Vektors noch korrekt ausgegeben, aber nach dem for_each ist der Vektor trotzdem leer. Warum? Ich hab ja in der Methode kopiereWort extra eine Referenz als Parameter für den Vektor genommen, damit dieser eben nicht kopiert wird.
-
boost::binderstellt eine Kopie vonleererVector. Alle Argumente, welche du anboost::bindübergibst, werden kopiert, sofern du es nicht anders angibst. Um eine Referenz zu übergeben, musst du zuerst einen Reference Wrapper erstellen. Dies geht mitboost::ref.Grüssli
-
Ja, jetzt klappt's.
Danke vielmals!
