alpenkönig Geschrieben 18. November 2009 Geschrieben 18. November 2009 Hallo zusammen, Ich habe folgendes Problem: Ich habe eine Datei mit dem folgenden Format: Die gesamte .txt - Datei ist in dutzende Zeitschritte (ramp point, time..) unterteilt. Für jeden Zeitschritt gibt es mehrere Unterkategorien wie "Forces from Surface Loads" und "Forces from Body Loads" usw. mit den entsprechenden Werten. Die Indizes sind für alle Zeitschritte an der gleichen Position. D.h. die Reihenfolge für beispielsweise "Forces from Surface Loads" ist immer: 1681,1689,1502,... -------------------------------------------------------------------------- SOLUTION AT RAMP POINT 1 TIME 0 -------------------------------------------------------------------------- FORCES FROM SURFACE LOADS : Index Face Fx Fy Fz 1681 14457 1.459187E+01 -3.793072E+03 0.000000E+00 Stream 1689 15182 7.431102E+02 -7.433599E+02 0.000000E+00 Duct 1502 14876 4.547474E-13 -2.273737E-13 0.000000E+00 Duct 1204 14604 1.653944E+03 -1.960825E+04 0.000000E+00 Zone **** 23097 0.000000E+00 -2.436386E+04 0.000000E+00 Void ... FORCES FROM BODY LOADS : Domain Fx Fy Fz 1 0.000000E+00 0.000000E+00 0.000000E+00 2 0.000000E+00 0.000000E+00 0.000000E+00 3 0.000000E+00 2.199441E-01 0.000000E+00 4 0.000000E+00 4.059419E-02 0.000000E+00 5 0.000000E+00 3.987269E-03 0.000000E+00 ... -------------------------------------------------------------------------- SOLUTION AT RAMP POINT 2 TIME 30 -------------------------------------------------------------------------- FORCES FROM SURFACE LOADS : Index Face Fx Fy Fz 1681 14457 1.459187E+01 -3.793072E+03 0.000000E+00 Stream 1689 15182 7.431102E+02 -7.433599E+02 0.000000E+00 Duct 1502 14876 4.547474E-13 -2.273737E-13 0.000000E+00 Duct 1204 14604 1.653944E+03 -1.960825E+04 0.000000E+00 Zone **** 23097 0.000000E+00 -2.436004E+04 0.000000E+00 Void ... FORCES FROM BODY LOADS : Domain Fx Fy Fz 1 0.000000E+00 0.000000E+00 0.000000E+00 2 0.000000E+00 0.000000E+00 0.000000E+00 3 0.000000E+00 2.199441E-01 0.000000E+00 4 0.000000E+00 4.059419E-02 0.000000E+00 5 0.000000E+00 3.987269E-03 0.000000E+00 ... -------------------------------------------------------------------------- SOLUTION AT RAMP POINT 3 TIME 60 -------------------------------------------------------------------------- ... Jetzt wäre es nützlich, wenn die Daten nach der jeweiligen Index/Domain-nummer für alle Zeitschritte sortiert werden. D.h. dass für jeden Zeitschritt jeweils die gleiche Zeile zusammengefasst wird. Also zuerst alle 1. Zeilen, dann alle 2. usw. Am Ende sieht es dann so aus: (Mit Einfügen der Zeit in die 1. Spalte) FORCES FROM SURFACE LOADS: Time Index Face Fx Fy Fz 00 1681 14457 1.459187E+01 -3.793072E+03 0.000000E+00 Stream 30 1681 14457 1.459187E+01 -3.793072E+03 0.000000E+00 Stream 60 1681 14457 ... ... ... Time Index Face Fx Fy Fz 00 1689 15182 7.431102E+02 -7.433599E+02 0.000000E+00 Duct 30 1689 15182 7.431102E+02 -7.433599E+02 0.000000E+00 Duct 60 1689 15182 ... ... ... FORCES FROM BODY LOADS : Time Domain Fx Fy Fz 00 1 0.000000E+00 0.000000E+00 0.000000E+00 30 1 0.000000E+00 0.000000E+00 0.000000E+00 60 1 ... Time Domain Fx Fy Fz 00 2 0.000000E+00 0.000000E+00 0.000000E+00 30 2 0.000000E+00 0.000000E+00 0.000000E+00 60 2 ... Zur besseren Übersichtlichkeit habe ich dir das Originalfile mit nur 3 von 181 Zeitschritten im Anhang beigefügt. Die Informationen ganz am Anfang mit (Domain, Speed,...) müssen nicht exportiert werden ebenso wie zahlreiche andere Unterkapitel. Was zählt sind nur die "Forces from Surface Loads" sowie die "F. from reactions at restrained Faces" und die "F. from reactions at point ties". Wenn möglich wäre es gut, dass jedes Unterkapitel in ein eigenes .txt file exportiert wird, um die Übersichtlichkeit zu verbessern. Ich habe dir einen bestehenden Code geschickt, der alle Daten exportiert und sortiert jedoch nur für sehr kleine Datenmengen brauchbar ist. #include <vector> #include <string> #include <iostream> #include <algorithm> #include <string.h> #include <stdlib.h> using namespace std; class myItem { public: myItem(int T, int S, int I, const string& L): Time(T), Section(S), Id(I), Line(L) {} int Time, Section, Id; string Line; bool operator < (const myItem& o) const { if (Section != o.Section) return Section < o.Section; if (Id != o.Id) return Id < o.Id; return Time < o.Time; } }; int main() { string line; vector <string> Sections, TableHeads; vector <myItem> AllData; int curTime, curSection, curId; // INPUT while (getline(cin,line).good()) { cerr << line << endl; char dummy; if (sscanf(line.c_str()," SOLUTION AT RAMP POINT %*d TIME %d",&curTime) == 1) { // A new ramp point and time, restart sections curSection = -1; } else if (line.find(':') != string::npos) { // A new heading string tablehead; getline(cin,tablehead); curSection++; if (Sections.size() <= curSection) { Sections.push_back(line); TableHeads.push_back(tablehead); } } else if (line.find_first_not_of("- \r\n\t")==string::npos) { // ignore line } else { // data line int curId = line[0] == '*'? (~0u)>>1 : atoi(line.c_str()); AllData.push_back(myItem(curTime,curSection,curId,line)); } } // SORT sort(AllData.begin(), AllData.end()); // OUTPUT curSection = -1; curId = -1; for (vector<myItem>::iterator i=AllData.begin(); i!= AllData.end(); i++) { if (i->Section != curSection) { curSection = i->Section; curId = -1; printf("\n%s\n", Sections[curSection].c_str()); } if (i->Id != curId) { curId = i->Id; printf("\nTime %s\n",TableHeads[curSection].c_str()); } printf("%02d %s\n",i->Time, i->Line.c_str()); } } Hoffe, du kannst mir da eine Hilfestellung geben Grüsseforces.zip Zitieren
Klotzkopp Geschrieben 18. November 2009 Geschrieben 18. November 2009 Ich habe dir einen bestehenden Code geschickt, der alle Daten exportiert und sortiert jedoch nur für sehr kleine Datenmengen brauchbar ist. Das ist doch mal eine tolle Fehlerbeschreibung Was läuft denn bei nicht sehr kleinen Datenmengen falsch? Zitieren
alpenkönig Geschrieben 18. November 2009 Autor Geschrieben 18. November 2009 Hallo Klotzkopp, Konnte nicht implementieren, dass es für jedes Unterkapitel ein eigenes .txt file erzeugt, da es so relativ unübersichtlich ist, wenn alles im selben file ist. Es funktioniert, aber wenn ich das Originalfile (400MB - 181 Zeitschritte) nehme ist der Prozessor überlastet Da ich nicht unbedingt alle Daten brauche, wäre es auch eine Möglichkeit, am Anfang ein Feature zu programmieren, das erlaubt, dass man aus einer Liste wählen kann, welche "Forces" und "Moments" man wirklich will. Das würde die Rechenzeit erheblich verkürzen, jedoch weiss ich nicht ob hier der Programmieraufwand exorbitant ansteigt Muss diese Aufgabe mit C++ lösen, da ich im Büro auf meinem Linux Computer nur einen einfachen Compiler habe und sonst nichts Hoffe, ich habe dich hiermit nicht zu sehr verwirrt. Grüsse Zitieren
alpenkönig Geschrieben 24. November 2009 Autor Geschrieben 24. November 2009 Hallo Klotzkopp, Ich habe mein Program ein bisschen modifiziert, sodass es nun alle Daten in ein separates "output.txt" - file schreibt. (ist auch im Anhang) Wie du aber siehst ist es ziemlich unübersichtlich, da es einfach alle Daten im source-file ("forces_prt.txt") sortiert und ausgibt. Wie implementiert man am besten, dass das Program nur Daten von bestimmten Kategorien extrahiert? Ich habe es versucht mit einer if-schlaufe nach "tablehead" suchen, habe es aber nicht hinbekommen Konkret bräuchte ich nur die "Forces from Reactions at Point Ties" und "Forces from Reaction at Restrained Faces" Wäre dir für eine Hilfestellung sehr dankbar Grüsse #include <vector> #include <string> #include <iostream> #include <algorithm> #include <string.h> #include <stdlib.h> #include <fstream> using namespace std; class myItem { public: myItem(int T, int S, int I, const string& L): Time(T), Section(S), Id(I), Line(L) {} int Time, Section, Id; string Line; bool operator < (const myItem& o) const { if (Section != o.Section) return Section < o.Section; if (Id != o.Id) return Id < o.Id; return Time < o.Time; } }; int main() { string line; vector <string> Sections, TableHeads; vector <myItem> AllData; int curTime, curSection, curId; // INPUT while (getline(cin,line).good()) { cerr << line << endl; char dummy; if (sscanf(line.c_str()," SOLUTION AT RAMP POINT %*d TIME %d",&curTime) == 1) { // A new ramp point and time, restart sections curSection = -1; } else if (line.find(':') != string::npos) { // A new heading string tablehead; getline(cin,tablehead); curSection++; if (Sections.size() <= curSection) { Sections.push_back(line); TableHeads.push_back(tablehead); } } else if (line.find_first_not_of("- \r\n\t")==string::npos) { // ignore line } else { // data line int curId = line[0] == '*'? (~0u)>>1 : atoi(line.c_str()); AllData.push_back(myItem(curTime,curSection,curId,line)); } } // SORT sort(AllData.begin(), AllData.end()); // OUTPUT std::ofstream output ("//gt//home//h113027//GT26//forces_moments//final1//output.txt"); curSection = -1; curId = -1; for (vector<myItem>::iterator i=AllData.begin(); i!= AllData.end(); i++) { if (i->Section != curSection) { curSection = i->Section; curId = -1; output << Sections[curSection].c_str() << std::endl; } if (i->Id != curId) { curId = i->Id; output << "\nTime " << TableHeads[curSection].c_str() << std::endl; } output << i->Time << std::endl << i->Line.c_str() << std::endl; } output.close(); } forces.zip Zitieren
Klotzkopp Geschrieben 24. November 2009 Geschrieben 24. November 2009 Du musst eigentlich nur bei bestimmten "Headings" die weitere Verarbeitung in der Leseschleife ein- oder ausschalten. Anbieten würde sich da zunächst eine einfach bool-Variable. Die setzt du in dem "heading"-if-Block entweder auf true oder false, und packst sie mit in die "ignore"-Bedingung. Zitieren
alpenkönig Geschrieben 24. November 2009 Autor Geschrieben 24. November 2009 Hallo Klotzkopp, Habe versucht deine guten Ratschläge zu implementieren. Habe aber noch einen Haken drin bei der Implentierung. Habe meine Zeilen blau markiert: #include <vector> #include <string> #include <iostream> #include <algorithm> #include <string.h> #include <stdlib.h> #include <fstream> using namespace std; class myItem { public: myItem(int T, int S, int I, const string& L): Time(T), Section(S), Id(I), Line(L) {} int Time, Section, Id; string Line; bool operator < (const myItem& o) const { if (Section != o.Section) return Section < o.Section; if (Id != o.Id) return Id < o.Id; return Time < o.Time; } }; int main() { string line; [COLOR="royalblue"] string header1 = "FORCES FROM REACTIONS AT POINT TIES:"; string header2 = "FORCES FROM REACTIONS AT RESTRAINED FACES :";[/COLOR] vector <string> Sections, TableHeads; vector <myItem> AllData; int curTime, curSection, curId; // INPUT while (getline(cin,line).good()) { cerr << line << endl; char dummy; if (sscanf(line.c_str()," SOLUTION AT RAMP POINT %*d TIME %d",&curTime) == 1) { // A new ramp point and time, restart sections curSection = -1; } else if (line.find(':') != string::npos) { // A new heading string tablehead; getline(cin,tablehead); curSection++; if (Sections.size() <= curSection) { Sections.push_back(line); TableHeads.push_back(tablehead); } } else if (line.find_first_not_of("- \r\n\t")==string::npos) { // ignore line } [COLOR="RoyalBlue"]else if (tablehead==header1 || tablehead==header2) { // data line[/COLOR] int curId = line[0] == '*'? (~0u)>>1 : atoi(line.c_str()); AllData.push_back(myItem(curTime,curSection,curId,line)); } else { // ignore line } } // SORT sort(AllData.begin(), AllData.end()); // OUTPUT std::ofstream output ("//gt//home//h113027//GT26//forces_moments//final1//output.txt"); curSection = -1; curId = -1; for (vector<myItem>::iterator i=AllData.begin(); i!= AllData.end(); i++) { if (i->Section != curSection) { curSection = i->Section; curId = -1; output << Sections[curSection].c_str() << std::endl; } if (i->Id != curId) { curId = i->Id; output << "\nTime " << TableHeads[curSection].c_str() << std::endl; } output << i->Time << std::endl << i->Line.c_str() << std::endl; } output.close(); } Vielen Dank schonmal für deine hilfreichen Bemerkungen Zitieren
Klotzkopp Geschrieben 25. November 2009 Geschrieben 25. November 2009 Wenn ich deine Beispieldaten richtig deute, wird in tablehead niemals "FORCES FROM REACTIONS AT POINT TIES:" drinstehen, sondern eher so etwas wie "Domain Fx Fy Fz", eben der Tabellenkopf. Zudem ist tablehead eine lokale Variable eines darüberliegenden if-Blocks und damit außerhalb nicht existent. Und für die Zukunft: "Habe noch einen Haken drin" ist keine gute Fehlerbeschreibung. Wenn Fehlermeldungen auftreten, dann teil uns die mit. Wenn nicht, dann beschreibe, was das beobachtete und das beabsichtigte Verhalten ist. Zitieren
alpenkönig Geschrieben 26. November 2009 Autor Geschrieben 26. November 2009 Hallo Klotzkopp, Das mit dem "tablehead" leuchted mir jetzt ein, aber ich verstehe die Zeile "} else if (line.find(':') != string::npos) {" nicht ganz. Das Program sucht nach dem ":" was ja dem Kapitelnamen (Forces...) entspricht. Die Bedeutung von string::npos habe nicht ganz verstanden (Ende des Strings?) Wie kann ich nun Daten von bestimmten Kapitelnamen und nicht "tablehead" extrahieren? Geht das in der gleichen Zeile, dass ich die nach ":" suche und sobald die Bedingung 'Forces from...' = true ist, die Daten exportiere? Danke dir sehr für deine hilfreiche Unterstützung #include <vector> #include <string> #include <iostream> #include <algorithm> #include <string.h> #include <stdlib.h> #include <fstream> using namespace std; class myItem { public: myItem(int T, int S, int I, const string& L): Time(T), Section(S), Id(I), Line(L) {} int Time, Section, Id; string Line; bool operator < (const myItem& o) const { if (Section != o.Section) return Section < o.Section; if (Id != o.Id) return Id < o.Id; return Time < o.Time; } }; int main() { string line; vector <string> Sections, TableHeads; vector <myItem> AllData; int curTime, curSection, curId; // INPUT while (getline(cin,line).good()) { cerr << line << endl; char dummy; if (sscanf(line.c_str()," SOLUTION AT RAMP POINT %*d TIME %d",&curTime) == 1) { // A new ramp point and time, restart sections curSection = -1; } else if (line.find(':') != string::npos) { // A new heading string tablehead; getline(cin,tablehead); curSection++; if (Sections.size() <= curSection) { Sections.push_back(line); TableHeads.push_back(tablehead); } } else if (line.find_first_not_of("- \r\n\t")==string::npos) { // ignore line } else { // data line int curId = line[0] == '*'? (~0u)>>1 : atoi(line.c_str()); AllData.push_back(myItem(curTime,curSection,curId,line)); } } // SORT sort(AllData.begin(), AllData.end()); // OUTPUT std::ofstream output ("//gt//home//h113027//GT26//forces_moments//final1//output.txt"); curSection = -1; curId = -1; for (vector<myItem>::iterator i=AllData.begin(); i!= AllData.end(); i++) { if (i->Section != curSection) { curSection = i->Section; curId = -1; output << Sections[curSection].c_str() << std::endl; } if (i->Id != curId) { curId = i->Id; output << "\nTime " << TableHeads[curSection].c_str() << std::endl; } output << i->Time << std::endl << i->Line.c_str() << std::endl; } output.close(); } Zitieren
Klotzkopp Geschrieben 26. November 2009 Geschrieben 26. November 2009 Die Bedeutung von string::npos habe nicht ganz verstanden (Ende des Strings?)Richtig. string::npos ist der Wert, den string::find zurückgibt, wenn der Suchstring nicht gefunden wird. Wie kann ich nun Daten von bestimmten Kapitelnamen und nicht "tablehead" extrahieren?Du brauchst nichts zu extrahieren. Es reicht doch, wenn du beim Erkennen einer neuen Überschrift prüfst, ob das eine ist, die für dich interessant ist oder nicht. Das ist ein Ja/Nein-Wert, also reicht eine bool-Variable. Wenn du einen neue Überschrift findest, setzt du diese Variable. Und in der weiteren Verarbeitung prüfst du sie. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.