Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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üsse

forces.zip

Geschrieben

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?

Geschrieben

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

Geschrieben

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

Geschrieben

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.

Geschrieben

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 ;)

Geschrieben

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.

Geschrieben

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(); 

}

Geschrieben
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.

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...