Einlesen einer Datei und Übergabe an Array ab einer bestimmten Zeile
-
Hallo C++ Experten,
ich versuche derzeit eine Datei einzulesen, bin mir aber nicht sicher wie ich das an einer bestimmten Zeile auslesen soll. Meine Datei besitzt folgendes Format:
------------------------------------------------------------------------
Berechnung
Anzahl der Punkte: 200 # Atome: 10Punkt 1 : 0.00000000 0.00000000 0.00000000 Gewichtung = 0.00500000
Energie 1 # mit Gewichtung 1.00000000
Atom a b c d
1 0.476 0.000 0.000 0.100
2 0.476 0.000 0.000 0.100
1 0.000 -0.000 -0.000 0.200
2 -0.000 -0.000 0.000 0.200Energie 2 # mit Gewichtung 1.00000000
Atom a b c d
1 0.476 0.000 0.000 0.300
2 0.476 0.000 0.000 0.300
1 0.000 -0.000 -0.000 0.400
2 -0.000 -0.000 0.000 0.400Energie 2 # mit Gewichtung 1.00000000
Atom a b c d
1 0.476 0.000 0.000 0.500
2 0.476 0.000 0.000 0.500
1 0.000 -0.000 -0.000 0.600
2 -0.000 -0.000 0.000 0.600....
------------------------------------------------------------------------Der Code, den ich mir bislang zusammengeschrieben habe, summiert über alle letzten Spalten:
#include <iostream> #include <fstream> #include <string> #include <sstream> #include <vector> using namespace std; int main() { int reihen = 0; int spalten = 0; string line; int ersteZahl = 0; vector<vector<double> > werte; vector<vector<double> > ergebnis; vector<double> reihentotal; ofstream Datei; ifstream in("datei.txt"); Datei.open("ausgelesene_datei.txt",ios::app); Datei.setf(ios::fixed); Datei.setf(ios::showpoint); Datei.precision(3); if(in.fail()) { cerr << "Datei kann nicht geoffnet werden" << endl; return -1; } Datei << "\n" << endl; // Speichere jede Zahl while(in.good()) { while(getline(in, line)) { istringstream stream(line); vector<double> tmp; double x; while (stream >> x) tmp.push_back(x); if (tmp.size() > 0) werte.push_back(tmp); } } // Pruefe ob die Spaltenanzahl sich veraendert hat oder nicht spalten = werte[0].size(); for (unsigned i = 1; i < werte.size(); ++i) { if (werte[i].size() != spalten) { cerr << "Reihe mit unterschiedlicher Spaltennummer" << endl; return -1; } } for (unsigned i = 0; i < werte.size(); ++i) { // Wenn eine Zahl mit 1 beginnt, fuege es der Reihe hinzu if (werte[i][0] == 1.0) ergebnis.push_back(werte[i]); // Wenn eine Zahl bzw. Zeile mit 2 beginnt, fuege es ebenfalls der Reihe hinzu if (werte[i][0] == 2.0) { for (unsigned j = 0; j < werte[i].size(); ++j) ergebnis.back()[j] += werte[i][j]; } } reihen = ergebnis.size(); Datei << "Anzahl der Reihen # " << reihen << endl; Datei << "Anzahl der Spalten # " << spalten << endl; Datei << " " << endl; for(int i=0; i < reihen; i++) { for(int j=4; j < spalten; j++) { Datei << ergebnis[i][j] << " " << " " << endl; } } for(int i=0; i < reihen; i++) { reihentotal.push_back(0.0); for (int j=1; j < spalten; j++) { reihentotal[i] += ergebnis[i][j]; } } Datei.close(); in.close(); return 0; }Die Ausgabe erfolgt als:
Anzahl der Reihen # 6
Anzahl der Spalten # 50.200
0.400
0.600
0.800
1.000
1.200Ich würde aber gerne über nur über die Blöcke mit Aufschrift "Energie 2 #" summieren, d.h. es sollte dann folgendes ausgegeben werden (unter Vernachlässigung des Blocks "Energie 1 #":
0.600
0.800
1.000
1.200Ich habe versucht eine "*.find function" mit String-Inhalt einzubauen, bevor die Werte bei "werte[i][0] == 1.0" und "werte[i][0] == 2.0" eingelesen werden, kriege es aber irgendwie nicht hin, obwohl es nur noch ein kleiner Schritt ist :(.
Ich wäre sehr dankbar, wenn mir jemand helfen könnte, wie ich es richtig zu parsen bzw. zu "tokenizen" habe.
Viele Dank im Voraus für jegliche Hilfe,
ThOr_Asgard
-
Der Code sieht einigermaßen furchtbar aus (was soll y.B. die
while(in.good())-Schleife?), dennoch sollte man das schnell einbauen können:Ersetze
while(getline(in, line)) {Durch:
bool inErgebnis2 = false; while(getline(in, line)) { if (boost::begins_with(line, "Ergebnis ")) { inErgebnis2 = boost::begins_with(line, "Ergebnis 2 #")); } if (!inErgebnis2) continue;(und
#include <boost/algorithm/string.hpp>)Alles ungetestet.
-
Vielen Dank schon mal für den Hinweis wob! Ich hatte auch schon daran gedacht an dieser Stelle mit "bool" es einzulesen, bekam aber als Fehlermeldung segmentation fault heraus.
Mich würde aber interessieren, ob es eine andere Lösung gibt, ohne dass ich "Boost" Header benutzen muss!?
Vielen Dank im Voraus!
-
Klar geht das ohne. Das ist sehr einfach nachzubauen. Habe aber keine Lust dazu, wenns schon ne fertige Lösung gibt und überlasse dir das als Übung.
-
Ähm, ich merke gerade, dass es starts_with statt begins_with heißt. Verdammt, immer diese unterschiedlichen String-Bibliotheken! Das kommt davon, wenn man ohne IDE im Forumseditor programmiert
