Datendatei aufsplitten, konvertieren und Einzelteilen speichern


  • Mod

    Du öffnest die Datei, suchst den Header. Liest die Länge und den Anfang der Daten aus dem Header. Springst zum Anfang und liest die Daten. Wandelst die Daten in dein gewünschtes Format um (habe ehrlich gesagt nicht verstanden, was du da überhaupt machen willst). Speicherst die Daten. Fertig.

    Dazu brauchst du: Solide Kenntnisse über Kontrollstrukturen, solide Kenntnisse über das binäre Lesen von Dateien, rudimentäre Mathekenntnisse.

    MS-Office-User schrieb:

    [Wall of text]

    Und bitte: Fasse dich kurz! Niemand hat Lust dir zu helfen, wenn er sich erstmal deine Lebensgeschichte durchlesen muss. Bitte präzise Fragen stellen und den Leser nicht mit irrelevanten Informationen überschwemmen.



  • SeppJ schrieb:

    Du öffnest die Datei, suchst den Header. Liest die Länge und den Anfang der Daten aus dem Header. Springst zum Anfang und liest die Daten. Wandelst die Daten in dein gewünschtes Format um (habe ehrlich gesagt nicht verstanden, was du da überhaupt machen willst). Speicherst die Daten. Fertig.

    Klingt einfach, zumindest wenn man weiss wie es geht. 🙄

    Nicht ganz was ich haben wollte, aber ich bin schon ganz zufrieden, dass ich es zumindest geschafft habe wenigstens den Header und das Inhaltsverzeichnis zu lesen und in DEZIMAL auf dem Bildschirm auszugeben.

    /*
    	Version 01
    	Header und Inhaltsverzeichnis lesen und als Dezimalzahl ausgeben. 
    	Daten-Dateiversion 55 mit 39 Containern.
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) 
    {
       int Zeilen[80];
       /*
           Dateiversion 55 hat 39 Container,
           d.h. 40 Zeilen im Inhaltsverzeichnis incl. Header.
           Bei 4 Byte macht das dann 80 Zeilen die gelesen werden müssen.
    	   Bei anderen Dateiversionen die Zeilenzahl anpassen!!!
       */ 
    
       FILE *Inhaltsverzeichnis;
       /*
           Name des Datensatzes. 
       */ 
    
       int i;
    
       Inhaltsverzeichnis = fopen("test.dat", "r+b");
       /*
           Öffnen der Datei des Datensatzes. 
       */ 
       if(Inhaltsverzeichnis != NULL)
          fread(&Zeilen, sizeof(int), 80, Inhaltsverzeichnis);
          /*
    		 Festlegen der Anzahl von Zeilen die gelesen werden sollen. 
    	  */ 
    
       for(i = 0; i < 80; i++)
          printf("Wert %d in Dezimal = %d\n", i, Zeilen[i]);
          /*
             Ausgabe von 4 Byte als Dezimalzahl untereinander. 
    		 Angefangen beim Header (2 Reihen), gefolgt von Datensatzlänge
    		 und Datensatzbeginn der einzelnen Container. Die Anordnung 
    		 in Form von Paaren funktioniert bisher nicht. Vielleicht
    		 mit fseek set oder current und je einer Schleife pro Container
    		 bzw. Datenpaar???
          */ 
    
     return EXIT_SUCCESS;
    }
    

    Länge und Start nebeneinander zu bekommen habe ich leider nicht hinbekommen, auch muss ich mal gucken wie ich die Datensätze des Headers nun zum Zerteilen der Datei nutzen kann. Ist mir noch ein Rätsel.


  • Mod

    Du machst da C, kein C++, daher kann ich dir nicht weiterhelfen. Du solltest wohl besser noch mal im ANSI C Forum fragen.



  • Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • SeppJ schrieb:

    Du machst da C, kein C++, daher kann ich dir nicht weiterhelfen. Du solltest wohl besser noch mal im ANSI C Forum fragen.

    Ups. Das erklärt mir auch warum ich das script auf Visual Express 2008 nicht compilieren konnte sondern nur auf meinem alten Visual 6.0. Wo wäre ich denn besser aufgehoben mit der Dateizerlegung, Datenumwandlung (IEEE754 zu Dezimal und Hex zu Dezimal) sowie ggf. später eine Datenkombinierung und Ausgabe in ein definiertes Textformat. C oder C++? Vom Grundsatz bastel ich ja mehr als alles andere, da sollte ich gleich bei der richtigen Basis anfangen zu basteln.



  • MS-Office-User schrieb:

    Wo wäre ich denn besser aufgehoben [...] C oder C++?

    Python.



  • nwp2 schrieb:

    Python.

    nicht doch wenn er sich schon hier eingefunden hat;)



  • nwp2 schrieb:

    MS-Office-User schrieb:

    Wo wäre ich denn besser aufgehoben [...] C oder C++?

    Python.

    Ne, vor Schlangen hab ich Angst. :p

    Dumm ist, dass mein altes Visual 6.0 nicht auf Vista funktioniert. Musste für das peinliche Script da oben extra meinen alten XP-Rechner aus der Mottenkiste holen, da ich mit dem gestern runtergeladenen Visual Express 2008 nicht zurecht kam. Naja, im Prinzip ist mir egal womit ich das am Ende mache, hauptsache ich bekomme es hin. Ich bastel heute abend mal weiter. Vielleicht bekomme ich ja doch noch was besseres hin als totaler Noob. MS Excel ist einfacher. 😃



  • hat hier nicht mal jemand geschrieben er verwendet vc++6.0 mit vista? evtl. läufts im kompatibilitäts modus? oder braucht admin rechte oder so?



  • noobLolo schrieb:

    hat hier nicht mal jemand geschrieben er verwendet vc++6.0 mit vista? evtl. läufts im kompatibilitäts modus? oder braucht admin rechte oder so?

    Vista meckert schon bei der Installationsidee. Dort wird direkt verweigert mit Hinweis auf fehlende Kompatiblität.

    So, ich hab's geschafft mir das Inhaltsverzeichnis praktisch komplett und sortiert auf dem Bildschirm auszugeben. Vermutlich eine ziemlich beknackte Art und Weise und ich bin noch nicht so weit, dass ich die Daten auch nutzen kann, aber schon mal etwas. 😃

    Nur das Teilen der Datenlänge mit der einzelnen Datensatzlänge klappt nicht. Ich dachte so könnte ich auch angeben wieviel Datensätze im jeweiligen Container sind.

    Hier mein Script für die ersten 8 Container. 🤡

    /*
    	Version 02
    	Header und Inhaltsverzeichnis lesen und als Datenbeginn 
             und -länge sortiert als Dezimalzahl ausgeben. 
    	Daten-Dateiversion 55 mit 39 Containern.
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
       int Zeilen[80];
       int s; 
       int l;
    
       FILE *Inhaltsverzeichnis;
    
       Inhaltsverzeichnis = fopen("test.dat", "r+b");
    
       if(Inhaltsverzeichnis != NULL)
    
          fread(&Zeilen, sizeof(int), 80, Inhaltsverzeichnis);
          /*
    		 Festlegen der Anzahl von Zeilen die insgesamt gelesen werden können. 
    	  */ 
    
       for(s = 3; s < 4; s++)
       for(l = 2; l < 3; l++)
    
    	  /*
    		 Angeben der einzelnen Daten die im folgenden ausgegeben werden.
    		 Vorgang wird so oft angepasst wiederholt bis das ganze Inhaltsverzeichnis ausgegeben wurde.
    	  */
    
          printf("Datencontainer 1:	Anfang:		%d\n			Laenge:		%d Byte\n			Datensaetze:	%d\n", Zeilen[s], Zeilen[l], l/72);
    
       for(s = 5; s < 6; s++)
       for(l = 4; l < 5; l++)
    
          printf("Datencontainer 2:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
       for(s = 7; s < 8; s++)
       for(l = 6; l < 7; l++)
    
          printf("Datencontainer 3:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
       for(s = 9; s < 10; s++)
       for(l = 8; l < 9; l++)
    
          printf("Datencontainer 4:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
       for(s = 11; s < 12; s++)
       for(l = 10; l < 11; l++)
    
          printf("Datencontainer 5:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
       for(s = 13; s < 14; s++)
       for(l = 12; l < 13; l++)
    
          printf("Datencontainer 6:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
       for(s = 15; s < 16; s++)
       for(l = 14; l < 15; l++)
    
          printf("Datencontainer 7:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
       for(s = 17; s < 18; s++)
       for(l = 16; l < 17; l++)
    
          printf("Datencontainer 8:	Anfang:		%d\n			Laenge:		%d Byte\n", Zeilen[s], Zeilen[l]);
    
     return EXIT_SUCCESS;
    }
    


  • MS-Office-User schrieb:

    Vista meckert schon bei der Installationsidee. Dort wird direkt verweigert mit Hinweis auf fehlende Kompatiblität.

    eigentlich logisch würd sich ja sonst keiner die neue version kaufen...



  • @MS-Office-User:
    Du kannst bei VCE2008 dem Compiler sagen das er es als C Datei compilieren soll. Der geht im normalfall immer von C++ aus.
    Das kann man in den Projekteinstellungen angeben (bei Erweitert (oder so, bei mir ist das auf englisch "Advanced"))

    Und hier nicht ganz so mühsam (ungetestet)

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct ContainerInfo_ {
       unsigned Offset;
       unsigned Size;
    } ContainerInfo;
    
    int main(void)
    {
       ContainerInfo containerInfo[40] = {0};
       int i = 1;
    
       FILE *Inhaltsverzeichnis;
    
       Inhaltsverzeichnis = fopen("test.dat", "r+b");
       fread(containerInfo, sizeof(ContainerInfo), 40, Inhaltsverzeichnis);
    
       for(; i < 40; ++i) {
         printf("Datencontainer %d:    Anfang:   %x\n"    
                "                      Laenge:   %u Byte\n\n", 
                i, containerInfo[i].Offset, containerInfo[i].Size);
       }
    }
    

    //Edit: Bug fix 😉
    //Edit: Copy'n'Paste bringt einfach zu viele Fehler 😛



  • evilissimo... das hier ist C, mach den bekackten _ weg 😉



  • Tim schrieb:

    evilissimo... das hier ist C, mach den bekackten _ weg 😉

    😛



  • evilissimo schrieb:

    @MS-Office-User:
    Du kannst bei VCE2008 dem Compiler sagen das er es als C Datei compilieren soll. Der geht im normalfall immer von C++ aus.
    Das kann man in den Projekteinstellungen angeben (bei Erweitert (oder so, bei mir ist das auf englisch "Advanced"))

    Das muss ich noch mal ausprobieren. Wenn ich ein neues Projekt gemacht habe, stand da jedenfalls nur C++ als Auswahlmöglichkeit, aber ich teste noch mal.

    evilissimo schrieb:

    Und hier nicht ganz so mühsam (ungetestet)

    ...
    

    Whow! 😮
    Funktioniert super, ist kurz und ich glaube ich verstehe es sogar. Vielen vielen Dank! 🙂
    Auch die Unterscheidung zwischen HEX-Wert und DEZ-Wert find ich klasse bei Anfang und Länge.
    Das mit %x und %u kannte ich nicht. Muss ich mit merken, macht so manche HEX-Konvertierung hinterher leichter.

    Eine doofe frage hätte ich aber noch für heute. Kann ich dieses Script auch als Basis nehmen um zusätzlich die Datei in die einzelnen Datencontainer zu zerlegen und einzeln als "Datenkontainer %d.dat" oder so abzuspeichern? Ich hab das auch vorher noch nicht hinbekommen, würde es aber jetzt erst mal mit Deiner scriptbasis weiter probieren.



  • Sie können den Code gerne als verwenden er ist ja für Sie gedacht gewesen 😉



  • evilissimo schrieb:

    Sie können den Code gerne als verwenden er ist ja für Sie gedacht gewesen 😉

    Vielen Dank! 🙂
    Du wäre für mich aber auch OK, fühl ich mich nicht soooo alt. 😉

    Die Einstellungen im Compilierer hab ich gefunden bei VC++2008E, nur wenn ich dann den Starte mit Vorgabe C bekomme ich im Gegensatz zu VB6.0 einen Fehler:

    1>------ Erstellen gestartet: Projekt: Evil, Konfiguration: Debug Win32 ------
    1>Kompilieren...
    1>cl : Befehlszeile warning D9035 : Die Option "Wp64" ist veraltet und wird in einer der nächsten Versionen entfernt.
    1>Inhalt_lesen_V3.c
    1>l:\c\inhalt_lesen_v3.c(16) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    1>        c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237): Siehe Deklaration von 'fopen'
    1>Manifest in Ressourcen wird kompiliert...
    1>Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
    1>Copyright (C) Microsoft Corporation.  All rights reserved.
    1>Verknüpfen...
    1>MSVCRTD.lib(crtexew.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_WinMain@16" in Funktion "___tmainCRTStartup".
    1>Debug\Evil.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.
    1>Das Buildprotokoll wurde unter "file://l:\c\Debug\BuildLog.htm" gespeichert.
    1>Evil - 2 Fehler, 2 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
    

    Änder ich fopen zu fopen_s klappt es auch nicht:

    1>------ Erstellen gestartet: Projekt: Evil, Konfiguration: Debug Win32 ------
    1>Kompilieren...
    1>cl : Befehlszeile warning D9035 : Die Option "Wp64" ist veraltet und wird in einer der nächsten Versionen entfernt.
    1>Inhalt_lesen_V3.c
    1>l:\c\inhalt_lesen_v3.c(16) : warning C4047: 'Funktion': Anzahl der Dereferenzierungen bei 'FILE **' und 'char [9]' unterschiedlich
    1>l:\c\inhalt_lesen_v3.c(16) : warning C4024: 'fopen_s': Unterschiedliche Typen für formalen und übergebenen Parameter 1
    1>l:\c\inhalt_lesen_v3.c(16) : error C2198: "fopen_s": Nicht genügend Argumente für Aufruf.
    1>l:\c\inhalt_lesen_v3.c(16) : warning C4047: '=': Anzahl der Dereferenzierungen bei 'FILE *' und 'errno_t' unterschiedlich
    1>Das Buildprotokoll wurde unter "file://l:\c\Debug\BuildLog.htm" gespeichert.
    1>Evil - 1 Fehler, 4 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
    


  • Hm, so richtig komm ich mit dem Einlesen und Abspeichern der einzelnen Datencontainer nicht zurecht. Als Grundlage benutze ich nun das Script von evilissimo:

    #include <stdio.h> 
    #include <stdlib.h> 
    
    typedef struct ContainerInfo_ { 
       unsigned Offset; 
       unsigned Size; 
    } ContainerInfo; 
    
    int main(void) 
    { 
       ContainerInfo containerInfo[40] = {0}; 
       int i = 1; 
    
       FILE *Inhaltsverzeichnis; 
    
       Inhaltsverzeichnis = fopen("test.dat", "r+b"); 
       fread(containerInfo, sizeof(ContainerInfo), 40, Inhaltsverzeichnis); 
    
       for(; i < 40; ++i) { 
         printf("Datencontainer %d:    Anfang:   %x\n"     
                "                      Laenge:   %u Byte\n\n", 
                i, containerInfo[i].Offset, containerInfo[i].Size); 
       } 
    }
    

    Meine Idee war,

    FILE *Datensatz;
    Datensatz = fopen("test.dat","r+b");
    

    zunächst zusätzlich einzufügen.

    Die Datenbereiche wollte ich dann anschließend mit den vorliegenden Daten des Inhaltsverzeichnisses und fseek markieren und mit getc kopieren:

    fseek(Datensatz, containerInfo[i].Offset, SEEK_SET); 
    c=getc(Datensatz)) != containerInfo[i].Size);
    

    Als Ausgabe hab ich zunächst ohne Erfolg printf probiert da ich noch nicht genau verstanden habe wie ich eine neue Datei erzeuge. Im Kopf habe ich hierfür im Moment

    creat("Datencontainer%d.dat", i, S_IREAD|S_IWRITE)) == -1)
    putc(c,stdout)
    

    aber soweit komme ich gar nicht erst. 😞

    Ich hab mich gerade auch mal durch ein paar Beispiele gequält, dort wird aber in der Regel keine neue Datei erzeugt und die Datentabellen sind auch alle Textdateien mit Komma oder Leerzeichen als Marker. Bin ich mit meinen Ideen da oben zumindest gedanklich ein wenig auf dem richtigen Weg oder eher total falsch?

    Naja, vielleicht probiere ich morgen erst noch mal ein wenig mit einer einzelnen, einfachen Textdatei und reinen FSEEK-Befehlen rum und gehe die Sache noch mal Stück für Stück an.



  • Nimm lieber fopen wie es in dem "Script" steht. Nur dass du nicht "r+b" nimmst, was bedeutet dass du die Datei ließt, aber auch schreiben kannst, und zwar binär, sondern "wb" für schreiben, binär (Vorsicht, eine Datei mit "wb" öffnen löscht ihren Inhalt!!!) oder wenn du es brauchst "w+b" zum binären schreiben mit der Möglichkeit zu lesen.
    Wenn du eine Datei mit "w"/"wb"/"w+"/"wb+" öffnest und sie existiert nicht, dann wird sie erstellt.
    Es gibt dann noch "a" für append=anhängen, da wird die Datei zum schreiben geöffnet aber nicht gelöscht, stattdessen wird zu Ende der Datei gesprungen.
    Zum schreiben nimmst du dann fwrite, hat dieselbe Syntax wie fread.



  • Hallo Zusammen!

    Ich bastel immer noch an dem Projekt rum, bin aber für meine Verhältnisse mit dem Ergebnis schon weitgehend zufrieden. Im Moment verzweifel ich an 3 Dingen die ich noch gerne implementieren möchte.

    1. Ich möchte das Programm über drag&drop nutzen können und den Dateinamen dabei behalten und auch für die Ausgabe der Textdatei nutzen. Drag&drop geht, ich muss aber den Namen definieren bzw. die Datei dann immer umbenennen. Ich hab viel versucht und auch gegoogled, crashe aber immer nur wenn ich was anderes versuche.

    2. Ich würde gerne einen Teil der Datencontainer vor der Ausgabe verknüpfen. Z.B. Container 1 und 2 oder 1 und 3:

    Container 1 schrieb:

    berlin
    duesseldorf
    bochum
    muenchen
    frankfurt
    ulm
    koeln

    Container 2 schrieb:

    689.084961;6
    728.915039;6
    -370.133331;6
    -339.866638;6
    156.000000;6
    174.000000;6
    1188.791016;3
    1239.155029;3
    1952.000000;3
    2012.822754;3
    -10.641739;3
    30.409887;3

    Als Ergebnis möchte ich

    Container 2 schrieb:

    689.084961;koeln
    728.915039;koeln
    -370.133331;koeln
    -339.866638;koeln
    156.000000;koeln
    174.000000;koeln
    1188.791016;muenchen
    1239.155029;muenchen
    1952.000000;muenchen
    2012.822754;muenchen
    -10.641739;muenchen
    30.409887;muenchen

    Geht das überhaupt mit der aktuelle Script-Lösung (s. unten)? Bisher hab ich mir die Zähne ausgebissen und denke selber das geht nicht so wie ich das Einlesen aufgebaut habe. Die Datei die ich erzeuge hat dagegen eine Datensatznummerierung die ich verwenden könnte wenn ich ein zweites Programm erstellen würde und dort dann die beiden Container als 2 CSV-Dateien kombiniere. Wäre das die bessere Lösung?

    3. Das Einlesen des 2ten Datencontainers ist etwas fehlerhaft. Ich lese die ersten Daten über Struct als FLOAT ein, habe aber ein Mischmasch aus Floatzahlen und einer einfachen Nummerierung (Diese verweist auf Daten aus einem anderen Container der hier nicht enthalten ist). Kann float und int in der selben Datenspalte trotz Struct unterscheiden und entsprechend richtig ausgeben?

    Hier der Quellcode den ich im Moment verwende:

    //QDATDecrypter.h
    
    #ifndef QDATDECRYPTER_H
    #define QDATDECRYPTER_H
    
    #pragma pack(push, QDATDECRYPTER_H)
    #include <vector>
    #pragma pack(pop, QDATDECRYPTER_H)
    
    #pragma pack(push, QDATDECRYPTER_H)
    #include <string>
    #pragma pack(pop, QDATDECRYPTER_H)
    
    struct TContainer
    {
    	int					mLength;			    // Länge des Datencontainers  
    	int					mOffset;			    // Offset - Startposition des Containers  
    };
    struct THeader
    {
    	char				mDateikennung[4];	    //  Die Dateikennung ist immer "QDAT"  
    	int					mVersion;  			    //	Versionsnummer, 0x09  
    	TContainer				mContainers[3];		        //	Containerverzeichnis, 3 Container gesamt
    };
    struct TStadt
    {
    	char				mName[64];			    // Stadt  
    	unsigned char		mData1[4];			    // erst mal ignoriert um die Datenanzahl klein zu halten, alles in Quelldatei auf 00 gesetzt
    	unsigned char		mData2[4];			    // erst mal ignoriert um die Datenanzahl klein zu halten, alles in Quelldatei auf 00 gesetzt
    };
    struct TCoordinate
    {
    	float				mData3Index;		    // Data3-Index  
    	int					mStadtIndex;		    // Stadtindex  
    };
    struct TInfo
    {
    	short				mNbData3;		        // Anzahl zusammengehöriger Data3-Werte, die ersten 6 sind immer floatwerte, 
    // wenn größer 6 sind die folgenden Werte eine Nummerierung die auf Werte in DATA4 verweist 
    // (nicht hier enthalten da Datei zur Übersicht gekürzt)  
    	short				mStadtIndex;		    // Stadtindex  
    };
    
    struct TMapQDat
    {
    	THeader					         mHeader;		  
    	std::vector<TStadt>	   mStaedte;		 
    	std::vector<TCoordinate>	 mCoordinates;	  
    	std::vector<TInfo>		   mInfos;		 
    };
    // Konstante der Dateikennung
    const std::string			cDateikennung	= "QDAT";
    
    // Konstante der Dateiversion							
    const int					cVersion		= 0x09;
    
    //Konstanten zur Identifizierung der einzelen Container							
    const int					cStadtContainer	  = 0x00; 
    const int					cCoordinateContainer	= 0x01; // Coordinates   
    const int					cInfoContainer		  = 0x02; // Infos  
    
    void debugInformations(const TMapQDat& pMap, FILE* pFile);
    
    bool readMap(const std::string& pFilename, TMapQDat& pMap);
    
    void freeMap(TMapQDat& pMap);
    
    bool isValid(const TMapQDat& pMap);
    
    #endif
    
    //QDATDecrypter.cpp
    
    #include "QDATDecrypter.h"
    #pragma pack(push, QDATDECRYPTER_H)
    #include <cstdio>
    #pragma pack(pop, QDATDECRYPTER_H)
    
    // Prüfen des Dateiheaders
    bool isValid(const TMapQDat& pMap)
    {
    	// 1. Prüfung der Dateikennung
    	if
    		(strncmp(pMap.mHeader.mDateikennung, cDateikennung.c_str(), 4) != 0)
    	{
    		return false;
    	}
    
    	// 2. Prüfung der Versionsnummer
    	if
    		(pMap.mHeader.mVersion != cVersion)
    	{
    		return false;
    	}
    
    	return true;
    }
    
    // Beginn des Einlesens - Header
    bool readHeader(FILE* pFile, TMapQDat& pMap)
    {
    	fread(&pMap.mHeader, 1, sizeof(THeader), pFile);
    
    	return isValid(pMap);
    }
    
    // 1. Einlesen Staedte 
    void readStadt(FILE* pFile, TMapQDat& pMap)
    {
    	int	lNbStaedte = pMap.mHeader.mContainers[cStadtContainer].mLength / sizeof(TStadt);
    
    	fseek(pFile, pMap.mHeader.mContainers[cStadtContainer].mOffset, SEEK_SET);
    
    	for
    		(int lStadtCounter = 0; lStadtCounter < lNbStaedte; ++lStadtCounter)
    	{
    		TStadt lStadt;
    
    		fread(&lStadt, 1, sizeof(TStadt), pFile);
    
    		pMap.mStaedte.push_back(lStadt);
    	}
    }
    
    // 2. Einlesen Coordinates
    void readCoordinate(FILE* pFile, TMapQDat& pMap)
    {
    	int	lNbData3 = pMap.mHeader.mContainers[cCoordinateContainer].mLength / sizeof(TCoordinate);
    
    	fseek(pFile, pMap.mHeader.mContainers[cCoordinateContainer].mOffset, SEEK_SET);
    
    	for
    		(int lCoordinateCounter = 0; lCoordinateCounter < lNbData3; ++lCoordinateCounter)
    	{
    		TCoordinate lCoordinate;
    
    		fread(&lCoordinate, 1, sizeof(TCoordinate), pFile);
    
    		pMap.mCoordinates.push_back(lCoordinate);
    	}
    }
    
    // 3. Einlesen Infos
    void readInfo(FILE* pFile, TMapQDat& pMap)
    {
    	int	lNbInfos = pMap.mHeader.mContainers[cInfoContainer].mLength / sizeof(TInfo);
    
    	fseek(pFile, pMap.mHeader.mContainers[cInfoContainer].mOffset, SEEK_SET);
    
    	for
    		(int lInfoeCounter = 0; lInfoeCounter < lNbInfos; ++lInfoeCounter)
    	{
    		TInfo lInfo;
    
    		fread(&lInfo, 1, sizeof(TInfo), pFile);
    
    		pMap.mInfos.push_back(lInfo);
    	}
    };
    
    // Vorbereiten der Datenausgabe
    void debugInformations(const TMapQDat& pMap, FILE* pFile)
    {
    	// Prüfen des Datenstreams
    	if
    		(! pFile)
    	{
    		printf("debugInformations :: Invalid stream handle.\n");
    		return ;
    	}
    
    	// Prüfen der Daten
    	if
    		(! isValid(pMap))
    	{
    		printf("debugInformations :: Invalid QDat-header.\n");
    		return;
    	}
    
    	// Start der Datenausgabe
    	fprintf(pFile, "Stand: 04.09.2010\n");
    
    	// Ausgabe 01 - Staedte
    	fprintf(pFile, "\n01 - Stadt Container\n");
    	fprintf(pFile, "#;Stadt\n");
    	for
    		(int lStadtCounter = 0; lStadtCounter < pMap.mStaedte.size(); ++lStadtCounter)
    	{
    	fprintf(pFile, "%d;%s\n", lStadtCounter, pMap.mStaedte[lStadtCounter].mName);
    	}
    	fprintf(pFile, "\n");
    
    	// Ausgabe 02 - Info-Side-Koordinaten
    	fprintf(pFile, "\n02 - Coordinate\n");
    	fprintf(pFile, "#;Koordinate*;Stadt(Index) - *nach 6 Koordinaten kommt eine Nummerierung\n");
    	for
    		(int lCoordinateCounter = 0; lCoordinateCounter < pMap.mCoordinates.size(); ++lCoordinateCounter)
    	{
    		fprintf(pFile, "%d;%f;%d\n", lCoordinateCounter, pMap.mCoordinates[lCoordinateCounter].mData3Index, pMap.mCoordinates[lCoordinateCounter].mStadtIndex);
    	}
    	fprintf(pFile, "\n");
    
    	// Ausgabe 03 - Info-Informationen
    	fprintf(pFile, "\n03 - Info Container\n");
    	fprintf(pFile, "#;Anzahl Koordinaten;Stadt(Index)\n");
    	for
    		(int lInfoCounter = 0; lInfoCounter < pMap.mInfos.size(); ++lInfoCounter)
    	{
    		fprintf(pFile, "%d;%d;%d\n", lInfoCounter, pMap.mInfos[lInfoCounter].mNbData3, pMap.mInfos[lInfoCounter].mStadtIndex);
    	}
    	fprintf(pFile, "\n");
    
    }
    // Lesen der Dateiinformationen
    bool readMap(const std::string& pFilename, TMapQDat& pMap)
    {
    	// Öffnen
    	FILE* lFile = fopen(pFilename.c_str(), "r+b");
    
    	// Prüfen ob vorhanden
    	if
    		(! lFile)
    	{
    		printf("readMap :: Invalid stream handle.\n");
    		return false;
    	}
    
    	// Lesen des Headers
    	if
    		(readHeader(lFile, pMap) == false)
    	{
    		printf("readMap :: Invalid QDat-header.\n");
    		return false;
    	}
    
      // Einlesen der Container:
      readStadt(lFile, pMap);
      readCoordinate(lFile, pMap);
      readInfo(lFile, pMap);
    
    	// Schließen der Datei
    	fclose(lFile);
    
    	return true;
    };
    
    void freeMap(TMapQDat& pMap)
    {
      pMap.mStaedte.clear();
      pMap.mCoordinates.clear();
      pMap.mInfos.clear();
    }
    
    //QDAT-Decrypter.cpp
    //Verweis auf Quell- und Zieldatei
    
    #include "QDATDecrypter.h"
    #pragma pack(push, MAIN)
    #include <cstdlib>
    #pragma pack(pop, MAIN)
    #include <iostream>
    using namespace std;
    
    int main(int pArgc, char** pArgv)
    {
    	TMapQDat	lMap;
    
    	cout<<"\nQDAT-Decrypter\nStand: 04.09.2010\n\n";
    	cout<<"Zu konvertierende Datei bitte in decrypt_me.QDAT umbenennen.\nENTER druecken wenn die Konvertierung begonnen werden kann.\n";cin.get();
    
    	readMap("decrypt_me.QDAT", lMap);
    
    	cout<<"Datei eingelesen. Konvertierung beginnt.\n";
    
    	FILE*	lFile = fopen("QDAT-Daten.txt", "w+");	
    	debugInformations(lMap, lFile);
    	fclose(lFile);
    
    	freeMap(lMap);
    
    	cout<<"\nKonvertierung erfolgreich beendet. \n\nDatei als Klartext mit dem Namen QDAT-Daten.txt gespeichert. \n\nZum Schliessen des Fensters bitte ENTER druecken!\n";cin.get();
    
    	return 0;
    };
    

    Entschuldigung für den schlechten Stil und den MischMasch zwischen C und C++. Noob am Werk. 😃
    Ich wäre für jeden Tipp dankbar, inmsbesondere wenn ich ihn als Anfänger und Hobbybastler auch verstehen und umsetzen kann. 🤡


Anmelden zum Antworten