Datei in einen vector lesen
-
Hallo zusammen,
habe hier http://www.c-plusplus.net/forum/p2391664#2391664 etwas gelesen, das ich nicht ganz verstehe. Wäre sehr nett, wenn mir jemand diese zweite Zeile kurz und knackig, aber noch verständlich erklären könnte:
std::ifstream stream{"Pfad.txt"}; std::vector<int> numbers{ std::istream_iterator<int>{stream},std::istream_iterator<int>{} };Anscheinend ist das die Kurzform für
int x; while(stream >> x) numbers.push_back(x);verstehe aber nicht wie und wieso?
Vielen Dank im Voraus
-
std::vector hat einen Konstruktor, der zwei Iteratoren entgegen nimmt.
Der macht in etwa folgendes:for (; begin != end; ++begin) push_back(*begin);Initialisiert also anhand eines Range.
std::istream_iterator ist ein spezieller Iterator, der beim Dereferenzieren ein Objekt vom Typen aus dem Templateargument aus dem übergebenen Stream liest. Siehe: http://en.cppreference.com/w/cpp/iterator/istream_iterator
Man erzeugt nun einen Iterator auf den Anfang der Datei und einen eins hinters Ende (der ohne Argument). Um den Rest kümmert sich der Range-Konstruktor.
-
Hallo,
Vielen Dank für deine Antwort, Nathan.
Vorallem das ein Iterator kein Argument hatte, hat mich etwas verwirt. Aber jetzt kapier ichs soweit ich es im Moment kapieren muss

LG
-
Vorallem das ein Iterator kein Argument hatte, hat mich etwas verwirt.
Das funktioniert folgendermaßen.
Nathan hat folgende Pseudo-Schleife gezeigt:
for (; begin != end; ++begin) push_back(*begin);Zwei Dinge fallen auf: Die Schleife bricht ab, sobald der erste gleich dem zweiten Iterator ist, und in jedem Durchgang wird der erste Iterator inkrementiert. Außerdem muss ein Iterator bei mehrfachem Dereferenzieren denselben Wert zurückliefern (was hier allerdings nicht benötigt wird).
istream_iteratorkapselt die oben beschriebenen Eigenschaften wie folgt: Initialisierst du denistream_iteratormit einer Referenz auf einen Stream, so speichert er einen Verweis auf diesen Stream, extrahiert den ersten Wert und speichert ihn in seiner Membervariable.Inkrementierst du nun den Iterator, extrahiert er einen neuen Wert aus dem Stream und speichert dessen Wert in seiner Membervariable.
Dereferenzierst du ihn, gibt er den Wert der Membervariable zurück.
War das nicht möglich, und der Stream geht in den Fehlerzustand, dann geht der Iterator in den "Leerzustand" und gleicht beim Vergleich dem leeren Iterator - nämlichstd::istream_iterator()(also einem, der ohne Konstruktorargumente initialisiert wurde.). Sobald dieser Fall eintritt, bricht Nathans Schleife ab - genau dann, wenn es nichts mehr zu extrahieren gibt.Das heißt, sehr grob geschieht folgendes in der Schleife
for (; begin != end /* während die Extraktionsoperation erfolgreich war */ ; ++begin /* Extrahiere nächsten Wert und speichere ihn */ ) push_back(*begin); // Füge den gespeicherten Wert des Iterators in den Container ein
-
Aah, jau jetzt ergibt alles einen Sinn

vielen Dank noch für den Zusatz ArcothLG