Daten kombinieren bei Verwendung von Pragma Pack und Struct?
-
Ich lese eine Datendatei mit verschiedenen Datensätzen mittels pragma pack und struct in C++ ein, konvertiere die verschiedenen Datentypen zu Dezimal wenn nötig und gebe die gesamte Datendatei mit allen verschiedenen Datensätzen als Klartext-Textdatei aus. Das klappt im Wesentlichen ganz prima, ich scheitere aber vollkommen bei dem Versuch einzelne Daten vor der Ausgabe zu kombinieren.
Als vereinfachtes Beispiel:
Datenpaket 1 enthält als Text einen Städtenamen, gefolgt von Einwohnerzahl und Größe. Enthalten sind zahlreiche Datenreihen bzw. Städte.
0 Berlin;111;111
1 Düsseldorf;111;2222
2 Wien;1111;1234
3 Dortmund;333;4444
4 ...struct TStadt { char mName[64]; unsigned char mData1[4]; unsigned char mData2[4]; };Datenpaket 2 kann z.B. verschiedene Straßendaten enthalten und einen Verweis auf die Stadt, in Form der Datenreihennummer aus Datenpaket 1.
0 3;1;3568:458
1 3;4;4586;3
2 2;75;474;1
3 ...struct TStrassen { short mStaedteIndex; // Stadt short mStrasseIndex; int mSumTSData; short mNbTSData; };Ich möchte vor der Datenausgabe den Datensatz des 2ten Paketes um den tatsächlichen Stadtnamen ergänzen, scheitere aber jedes mal kläglich. Geht das überhaupt bei meiner Einlesemethode?
Ziel:
0 Dortmund;1;3568:458
1 Dortmund;4;4586;3
2 Wien;75;474;1
3 ...Meine Datendateien sind riesig und auch mein komplettes Script ist recht lang, daher kann ich nicht alles posten oder hochladen. Ich möchte am Ende auch einige Verknüpfungen mehr in der Datei machen als nur die eine da oben.
Vielleicht sollte ich noch einen Teil des scripts posten mit dem ich die Einlese und später dann die Textausgabe vornehme:
// Einlesen 1. Teil - Städte (786432DEZ / C0000HEX Datensatzlänge) void readStadt(FILE* pFile, TMapDAT& pMap) { int lNbStaedte = pMap.mHeader.mLumpes[cStadtLump].mLength / sizeof(TStadt); // Zum Datenbeginn springen fseek(pFile, pMap.mHeader.mLumpes[cStadtLump].mOffset, SEEK_SET); for (int lStadtCounter = 0; lStadtCounter < lNbStaedte; ++lStadtCounter) { TStadt lStadt; fread(&lStadt, 1, sizeof(TStadt), pFile); pMap.mStaedte.push_back(lStadt); } }P.S.: Hobbybasteler am Werk...

-
Dein Einlesen ist C und nicht C++
http://www.cplusplus.com/reference/iostream/fstream/
-
wx++ schrieb:
Dein Einlesen ist C und nicht C++
http://www.cplusplus.com/reference/iostream/fstream/Ich glaube ich bin zu dumm dafür. Was ich auch versuche um die Daten zu kombinieren endet in Fehlern und crashes. Ich hab mir extra erst mal eine kleine Datendtei gebaut und die ganzen scripts angepasst und verkleinert um mehr Übersicht zu haben und selbst damit komm ich nicht weiter. Aber ganz nebenbei, ich have CPP und h-Dateien erstellt, also ist das doch C++ und nicht C - oder?

-
MS-Office-User schrieb:
Ich lese eine Datendatei mit verschiedenen Datensätzen mittels pragma pack und struct in C++ ein, ...
0 Berlin;111;111
1 Düsseldorf;111;2222
2 Wien;1111;1234
3 Dortmund;333;4444
4 ...struct TStadt { char mName[64]; unsigned char mData1[4]; unsigned char mData2[4]; };...
Als Erstes fällt mir auf, dass in Deinem Beispiel die Daten unterschiedliche Länge haben (Städtenamen) - berücksichtigt Deine Einleseroutine das?
Als Zweites, dass Du nicht die (praktischen, sicheren, ...) C++-Mittel verwendest:
string, ifstream, operator>>(), vector, map, ...und schließlich, dass ich keine Fehlerbeschreibung in Deinem Text finde (du "scheiterst"?!?, Was meinst Du mit "Verknüpfung"?
Ich skizziere mal kurz, wie ich so ein Einlesen normalerweise löse:
#include <fstream> using std::ifstream; #include <string> using std::string; #include <vector> using std::vector; #include <iostream> using std::cout; struct Stadt { string name; long data1, data2; // sind doch nur Zahlen, oder? }; int main() { ifstream in("MeineDatei.txt"); vector<Stadt> staedte; while(in) { Stadt stadt; char trenner; in >> stadt.name; in >> trenner; // Semikolon überspringen in >> stadt.data1; in >> trenner; // Semikolon überspringen in >> stadt.data2; in >> trenner; // Semikolon überspringen staedte.push_back(stadt); } // Ab hier kann ich auf die n. Stadt mittels staedte[n-1] zugreifen ... // Hier z.B. einfach Ausgabe auf die Konsole for(size_t i=0; i<staedte.size(); ++i) cout << i << ". Stadt: name = " << staedte[i].name << ", data1 = " << staedte[i].data1 << ", data2 = " << staedte[i].data2 << "\n"; return 0; };Da kann man natürlich noch eine Menge verbessern (operator>>(Stadt&) , zeilenweise einlesen, Trennerhandling besser, operator<<() passend dazu, Fehlertoleranz (gerade bei großen Files wichtig), Ausgabe via iterator, ....), aber schon mit der einfachen Variante bekommst Du ein recht gute Fehlerbehandlung (z.B. String-Längen), einen Typkonvertierung, leichte Erweiterbarkeit, Übersichtlichkeit... geschenkt.
Kann es sein, dass Du ein "Datenmodell in C++" abzubilden versuchst? ("Index", "Verknüpfung", ... weisen für mich darauf hin) Dann solltest Du Dir unbedingt die StdLib-Container intensiv ansehen ("draufschaffen") und in 99,9% der Fälle auch verwenden!
Gruß,
Simon2.