Wertetabelle aus Datei mit unbekannter Größe auslesen
-
Hallo,
ich habe ein funktionierendes Beispiel für mein Problem, jedoch bin ich mit der Lösung nicht zufrieden.
Zuerst habe ich eine Datei folgender Form:
0 1 2 3 4 5 6 7 8 9Die Länge der Datei ist unbekannt und ich möchte jetzt die linke Spalte in einen x-Koordinaten-vector und die rechte Spalte in einen y-Koordinaten-vector schreiben. Dazu zähle ich zuerst die Anzahl der Zeilen und lese in einem weiteren Schritt die Daten ein, wie in diesem Minimalbeispiel der Fall:
#include <iostream> #include <fstream> #include <vector> #include <sstream> // string using namespace std; int main() { vector<double> x; vector<double> y; //Pfad aus Datei auslesen fstream datei; datei.open("kreis.dat"); int anzahl = 0; string zeile; while(getline(datei, zeile)) anzahl++; cout << anzahl << endl; datei.close(); datei.open("kreis.dat"); for(int i=0; i<anzahl; i++) { int tmp[2]; datei >> tmp[0] >> tmp[1]; x.push_back(tmp[0]); y.push_back(tmp[1]); } datei.close(); for (int i=0; i <x.size(); i++) cout << x[i] << " " << y[i] << endl; return 0; }Jedoch müsste es ja möglich sein in jedem while-Schleifenschritt den String in zwei doubles aufzuteilen und zu speichern und dass bis zum Ende der Datei, jedoch ist mir ein Aufteilen eines Strings in zwei Zahlen nicht gelungen.
Vielen Dank für die Mithilfe,
phanlipo
-
Ungetestet:
#include <iostream> #include <fstream> #include <vector> #include <string> #include <sstream> using namespace std; int main() { vector<double> x; vector<double> y; //Pfad aus Datei auslesen fstream datei; datei.open("kreis.dat"); string zeile; while(getline(datei, zeile)) { double a,b; stringstream ss( zeile ); ss >> a >> b; x.push_back(a); y.push_back(b); } cout << x.size() << endl; datei.close(); for (int i=0; i <x.size(); i++) cout << x[i] << " " << y[i] << endl; return 0; }
-
Vielen Dank, das klappt prima. Doch einfacher als gedacht.
-
phanlipo schrieb:
ich habe ein funktionierendes Beispiel für mein Problem, jedoch bin ich mit der Lösung nicht zufrieden.
Mir scheint Dein Code löst ein Problem, das Du gar nicht hast.
Willst Du wirklich zwei unabhängige Vektoren mit lauter Zahlen?
Mir dünkt Du willst eigentlich Positionen auslesen, oder Koordinaten, oder Tupel - jedenfalls zwei Werte, die zusammen einen Sinn ergeben.
Nennen wir's mal pos:
struct pos{ int x,y; };Jetzt hast Du ein File, in dem in jeder Zeile ein
posbeschrieben durch seine beiden Member steht.
Also schreibst Du Dir einenoperator>>()der aus einer solchen Zeile ein pos zusammenbaut:std::istream& operator>>(std::istream& in, pos& p){ return in >> p.x >> p.y; }Damit kannst Du jetzt ein
posaus einem Stream extrahieren.Und das war's auch schon.
Du kannst das Spielchen jetzt für die Ausgabe wiederholen.Im folgenden bastel ich insgesamt vier solcher Operatoren. Nur zur Veranschaulichung - die letzten beiden finde ich reichlich überflüssig.
#include <fstream> #include <iostream> #include <vector> struct pos{ int x,y; }; typedef std::vector<pos> position_table; std::istream& operator>>(std::istream& in, pos& p){ return in >> p.x >> p.y; } std::ostream& operator<<(std::ostream& out, const pos& p){ return out << p.x << '/' << p.y; } std::istream& operator>>(std::istream& in, position_table& positions){ pos p; while(in>>p) positions.push_back(p); return in; } std::ostream& operator<<(std::ostream& out, const position_table& positions){ for( const auto& p : positions) out << p << '\n'; return out; } int main(){ position_table positions; std::ifstream file("data.txt"); file>>positions; std::cout << positions; }
-
Das Puffern der Zeile ist völlig überflüssig.
#include <iostream> #include <sstream> #include <vector> #include <iterator> #include <algorithm> int main() { using namespace std; istringstream stream{"4 8 6 5 7 1 2 8"}; // Ob die beiden Paare durch einen Zeilenumbruch getrennt sind oder nicht, ist irrelevant. // (Ich nehme an, die Zeilenumbrüche sind in der Datei nur der Lesbarkeit wegen?) vector<double> x_vector, y_vector; // Die beiden vectors. double x, y; while( stream >> x >> y ) { x_vector.push_back(x); y_vector.push_back(y); } // Ausgabe copy( begin(x_vector), end(x_vector), ostream_iterator<double>{cout << "X: ", " "} ); copy( begin(y_vector), end(y_vector), ostream_iterator<double>{cout << "Y: ", " "} ); }Edit: Furble war schneller.
Mir dünkt Du willst eigentlich Positionen auslesen, oder Koordinaten, oder Tupel - jedenfalls zwei Werte, die zusammen einen Sinn ergeben.

-
std::istream& operator>>(std::istream& in, position_table& positions){ pos p; while(in>>p) positions.push_back(p); return in; }
std::istream& operator>>(std::istream& in, position_table& positions) { std::copy( std::istream_iterator<pos>(in), std::istream_iterator<pos>(), std::back_inserter(positions) ); return in; }(Ungetestet)
-
Sone schrieb:
std::istream& operator>>(std::istream& in, position_table& positions){ pos p; while(in>>p) positions.push_back(p); return in; }
std::istream& operator>>(std::istream& in, position_table& positions) { std::copy( std::istream_iterator<pos>(in), std::istream_iterator<pos>(), std::back_inserter(positions) ); return in; }(Ungetestet)
wozu?
-
wozu?
Nun, die Devise ist doch, immer die Standard-Bibliothek ausschöpfen? Nackte Schleifen vermeiden?
-
Sone schrieb:
wozu?
Nun, die Devise ist doch, immer die Standard-Bibliothek ausschöpfen? Nackte Schleifen vermeiden?
Nö, sicher nicht.
Mach besser den Fehler weg.
-
volkard schrieb:
Mach besser den Fehler weg.
Der einzige Fehler den ich sehe, ist, dass der Container nicht geleert wird.

std::istream& operator>>(std::istream& in, position_table& positions) { positions.clear(); pos p; while(in>>p) positions.push_back(p); return in; }
-
Sone schrieb:
Der einzige Fehler den ich sehe, ist, dass der Container nicht geleert wird.
Den meinte ich auch.
-
Auch falsch. Ein neuer Container sollte erstellt werden und dann move-assigned werden.
-
Kellerautomat schrieb:
Auch falsch. Ein neuer Container sollte erstellt werden und dann move-assigned werden.
Inwiefern ist das besser?
-
Kellerautomat schrieb:
Auch falsch. Ein neuer Container sollte erstellt werden und dann move-assigned werden.
Jo, man wird wohl erwarten, daß wenn der op>> failt, der vector unverändert bleibt.
-
Auch falsch
Falsch!
Ansichtsache, problemspezifisch, sollte spezifiziert warden.