Einzelne Zeilen ausgeben
-
Schlagt mich bitte nicht, ich bin neu hier und habe versucht soviel wie möglich über mein Problem in Erfahrung zubringen.
Ich habe es mir zur Aufgabe eine Textdatei nach bestimmten „Werten“ durchsuchen zu können.
Kommt dieser Wert vor, soll die ganze Zeile (in der der Wert amsteht) im String in einen weiteren String kopiert und bis zum ende der Datei weitergesucht werden. Der gesuchte Wert steht immer am Anfang der der Zeile.
Leider schaffe ich es nur die Datei nach dem Wert zu durchsuchen und die Position der gefunden Werte auszugeben.Vielleicht kennt Ihr ja eine Möglichkeit und könnt helfen.
#include <Windows.h> #include <iostream> #include <fstream> #include <string> #include <iterator> #include <sstream> #include <vector> using namespace std; int main() { char path1[MAX_PATH + 1] = { 0 }; OPENFILENAME datei1 = { sizeof(OPENFILENAME), 0, 0, "*.txt\0\0", 0, 0, 0, path1, MAX_PATH, 0, 0, ".\\", "Ansys - Datei Auswählen", 0 }; if (FALSE == GetOpenFileName(&datei1)) { MessageBox(0, "Ungültige Datei!", "Fehler", 0); /*Fehler bei Dateiauswahl*/ return 0; } else MessageBox(0, path1, "O.K.", MB_ICONQUESTION); /*Richtige bei Dateiauswahl*/ char path2[MAX_PATH + 1] = { 0 }; OPENFILENAME datei2 = { sizeof(OPENFILENAME), 0, 0, "*.txt\0\0", 0, 0, 0, path2, MAX_PATH, 0, 0, ".\\", "OpenGeoSys - Datei Auswählen", 0 }; // Beginn auslesen der Datei mit dem "Path1" cout << "Ansys - Dateipfad:" << path1 << endl; cout << endl; ifstream in(path1); ostringstream s; s << in.rdbuf(); // std::ostream& operator<<(std::ostream&, std::streambuf*) liest den kompletten Inhalt string myData = s.str(); // Ende auslesen der Datei mit dem "Path1" //String myData nach "510" Durchsuchen std::string zeile(myData); std::string suche("510"); std::vector<std::string::size_type> positionen; // lieber ein std::vector als ein Array std::string::size_type cur_pos = zeile.find(suche); // erstes Auftreten finden while (cur_pos != std::string::npos) { // falls etwas gefunden wurde -> weitersuchen positionen.push_back(cur_pos); cur_pos = zeile.find(suche, ++cur_pos); // ++cur_pos um ab der nächsten Position zu suchen } for (std::vector<std::string::size_type>::const_iterator beg(positionen.begin()), end(positionen.end()); beg != end; ++beg) std::cout << "Position -> " << *beg << "\n"; getchar(); return 0; }
Beispiel Datei:
514,6,7,1,9,1,11,1,13,1,15,1,17,1; 5P 3 510,55,1,1,19; 7P 4 510,57,1,1,21; 9P 5 510,59,1,1,23; 11P 6 510,61,1,1,25; 13P 7 510,63,1,1,27; 15P 8 510,65,1,1,29; 17P 9 508,4,0,69,1,0,0,0,69,2,1,0,0,69,3,0,0,0,69,4,0,0; 19P 10 508,4,0,69,5,0,0,0,69,4,1,0,0,69,6,0,0,0,69,7,0,0; 21P 11 508,4,0,69,8,0,0,0,69,7,1,0,0,69,9,0,0,0,69,10,0,0; 23P 12 508,4,0,69,11,0,0,0,69,10,1,0,0,69,12,0,0,0,69,2,0,0; 25P 13 508,4,0,69,11,1,0,0,69,1,1,0,0,69,5,1,0,0,69,8,1,0; 27P 14 508,4,0,69,12,1,0,0,69,9,1,0,0,69,6,1,0,0,69,3,1,0; 29P 15 126,1,1,0,0,1,0,0.,0.,4.,4.,1.,1.,30.,0.,0.,30.,0.,40.,0.,4.,0., 31P 16 0.,0.; 31P 17 126,1,1,0,0,1,0,0.,0.,6.,6.,1.,1.,30.,0.,0.,30.,60.,0.,0.,6.,0., 33P 18 0.,0.; 33P 19 126,1,1,0,0,1,0,-4.,-4.,0.,0.,1.,1.,30.,60.,40.,30.,60.,0.,-4., 35P 20 0.,0.,0.,0.; 35P 21 126,1,1,0,0,1,0,0.,0.,6.,6.,1.,1.,30.,0.,40.,30.,60.,40.,0.,6., 37P 22 0.,0.,0.; 37P 23 126,1,1,0,0,1,0,0.,0.,3.,3.,1.,1.,30.,0.,40., 39P 24 4.44089209850063D-015,0.,40.,0.,3.,0.,0.,0.; 39P 25 126,1,1,0,0,1,0,-3.,-3.,0.,0.,1.,1.,4.44089209850063D-015,60., 41P 26 40.,30.,60.,40.,-3.,0.,0.,0.,0.; 41P 27 126,1,1,0,0,1,0,0.,0.,6.,6.,1.,1.,4.44089209850062D-015,0.,40., 43P 28 4.44089209850062D-015,60.,40.,0.,6.,0.,0.,0.; 43P 29 126,1,1,0,0,1,0,0.,0.,4.,4.,1.,1.,4.44089209850062D-015,0.,40., 45P 30 0.,0.,0.,0.,4.,0.,0.,0.; 45P 31 126,1,1,0,0,1,0,-4.,-4.,0.,0.,1.,1.,0.,60.,0., 47P 32 4.44089209850062D-015,60.,40.,-4.,0.,0.,0.,0.; 47P 33 126,1,1,0,0,1,0,0.,0.,6.,6.,1.,1.,0.,0.,0.,0.,60.,0.,0.,6.,0., 49P 34 0.,0.; 49P 35 126,1,1,0,0,1,0,0.,0.,3.,3.,1.,1.,0.,0.,0.,30.,0.,0.,0.,3.,0., 51P 36 0.,0.; 51P 37 126,1,1,0,0,1,0,-3.,-3.,0.,0.,1.,1.,30.,60.,0.,0.,60.,0.,-3.,0., 53P 38 0.,0.,0.; 53P 39 128,1,1,1,1,0,0,1,0,0,0.,0.,4.,4.,0.,0.,6.,6.,1.,1.,1.,1.,30., 55P 40 0.,40.,30.,0.,0.,30.,60.,40.,30.,60.,0.,0.,4.,0.,6.; 55P 41 128,1,1,1,1,0,0,1,0,0,-1.97215226305253D-031, 57P 42 -1.97215226305253D-031,3.,3.,0.,0.,6.,6.,1.,1.,1.,1., 57P 43 4.44089209850062D-015,0.,40.,30.,0.,40.,4.44089209850062D-015, 57P 44 60.,40.,30.,60.,40.,-1.97215226305253D-031,3.,0.,6.; 57P 45 128,1,1,1,1,0,0,1,0,0,0.,0.,4.,4.,0.,0.,6.,6.,1.,1.,1.,1.,0.,0., 59P 46 0.,4.44089209850062D-015,0.,40.,0.,60.,0.,4.44089209850062D-015, 59P 47 60.,40.,0.,4.,0.,6.; 59P 48 128,1,1,1,1,0,0,1,0,0,0.,0.,3.,3.,0.,0.,6.,6.,1.,1.,1.,1.,30., 61P 49 0.,0.,0.,0.,0.,30.,60.,0.,0.,60.,0.,0.,3.,0.,6.; 61P 50 128,1,1,1,1,0,0,1,0,0,-2.,-2.,2.,2.,-1.5,-1.5,1.5,1.5,1.,1.,1., 63P 51 1.,0.,0.,40.,0.,0.,0.,30.,0.,40.,30.,0.,0.,-2.,2.,-1.5,1.5; 63P 52 128,1,1,1,1,0,0,1,0,0,-2.,-2.,2.,2.,-1.5,-1.5,1.5,1.5,1.,1.,1., 65P 53 1.,0.,60.,0.,0.,60.,40.,30.,60.,0.,30.,60.,40.,-2.,2.,-1.5,1.5; 65P 54 502,8,30.,0.,0.,30.,0.,40.,30.,60.,0.,30.,60.,40., 67P 55 4.44089209850062D-015,0.,40.,4.44089209850062D-015,60.,40.,0., 67P 56 0.,0.,0.,60.,0.; 67P 57 504,12,31,67,1,67,2,33,67,1,67,3,35,67,4,67,3,37,67,2,67,4,39, 69P 58 67,2,67,5,41,67,6,67,4,43,67,5,67,6,45,67,5,67,7,47,67,8,67,6, 69P 59
VG Nubivec
-
Lies dann die Datei am besten auch zeilenweise ein:
string zeile; while(getline(in, zeile) { if (zeile.find(suche, 0) != string::npos) { cout << zeile; } }
-
Weiters ist
find() != npos
kein passender Test.Der würde auch bei z.B.
0,510,0,0
oder
1051000,0,0
true
ergeben - was aber vermutlich nicht erwünscht ist.
-
Da der Wert ja immer am Anfang steht, könnte man bei find auf 0 prüfen.
-
Wenn man sich darauf verlassen kann, dass davor nicht irgendwelche Leerzeichen o.ä. stehen, dann wäre das schonmal ne Verbesserung.
Wobei man dann immer noch false positives bei z.B.510123,0,0
hätte.
=> Vielleicht eher
zeile.substr(0, 4) == "510,"
ps: Wobei das Float-Zahlen zu sein scheinen.
Stellt sich die Frage: kann die Zeile statt mit "510," auch mit "510.0," anfangen?
-
Die "saubere" Variante wäre also, das erste "," oder ";" zu finden, und den Teil davor als Float-Zahl zu parsen.
Die so gewonnene Float-Zahl kann man dann mit 510 vergleichen.Bzw. wenn einem der Vergleich einer Float-Zahl unheimlich ist, kann man sich den Substring zwischen Zeilenanfang und "," bzw. ";" rausschneiden, und dann:
* Alle Nullen vorne entfernen * Gucken ob der String nen "." enthält. Wenn ja: * Alle Nullen hinten entfernen * Wenn der String dann mit "." endet auch den "." entfernen
=> Danach muss der String exakt "510" sein.
Dabei kann man dann auch - falls das Dateiformat das erlaubt - führende Leerzeichen/Tabs/... entfernen.
-
das ist ein bisschen ein komisches Format.
Soll z.B. "-1.97215226305253D-031" eine Zahl in Exponentialschreibweise sein? üblich wäre "-1.97215226305253E-031" - also mit 'E' oder 'e'Kannst Du uns mehr über die Bedeutung des Inhalts der Datei sagen?
-
Das sieht nach IGES aus.
-
Oh - tatsächlich. Nach Fortran hat das ja gleich gerochen. Und in Spalte 73 steht der Typ - hier 'P' für Parameterdata. Die Lochkarte lässt grüßen
Dann reicht es nicht(!) aus, nach einer "510,.." am Anfang der Zeile zu suchen. Denn es gibt auch mehrzeilige 'Formate' wie 126 oder 128 und dort könnte ja eine 510 als Parameter auftauchen und zufällig am Anfang der Zeile stehen.
Folglich sollte zunächst die erste Zahl gelesen werden und anschließend alles bis zum nächsten ';' überlesen werden, falls es keine 510 ist.