Chunks in Datei schreiben und auslesen



  • Hallo,
    ich versuche gerade Daten aus einem Programm binär in eine Datei zu speichern und dann wieder auszulesen. Als Beispiel dient hier der String "Hallo ich bins". Den will ich 4 mal in eine Chunkbasierte-Datei schreiben und anschließend wieder auslesen:

    enum Typen
    {
    	PRODUKTIONSGEBAUDE,
    	ARBEITERGEBAUDE,
    	KARTE,
    	GLOBALS,
    	AUFGABEN
    };
    
    struct ChunkHeader
    {
    	Typen	ChunkTyp;
    	DWORD	dwDataSize;
    };
    
    ChunkHeader CH;
    DWORD		Anzahl;
    FILE*		pFile;
    
    pFile = fopen(pcFilename, "wb");
    
    char acText[256];
    DWORD Grosse;
    strcpy(acText, "Hallo ich bins");
    
    CH.ChunkTyp = AUFGABEN;
    //Chunkheader schreiben
    fwrite(&CH, sizeof(ChunkHeader), 1, pFile);
    Anzahl = 4;
    fwrite(&Anzahl, sizeof(DWORD), 1, pFile);
    
    for(int i = 0; i < 4; i++)
    {
    	Grosse = sizeof(acText);
    	fwrite(&Grosse, sizeof(DWORD), 1, pFile);
    	fwrite(acText, Grosse, 1, pFile);
    }
    fclose(pFile);
    
    char actext[256];
    pFile = fopen(pcFilename, "rb");
    if(pFile == NULL) { cout << "Fehler beim Laden\n"; return 1;}
    
    while(!feof(pFile))
    {
    	//Chunkheader lesen:
    	fread(&CH, sizeof(ChunkHeader), 1, pFile); 
    	cout<<"DRIN";
    	if(CH.ChunkTyp == AUFGABEN)
    	{
    		fread(&Anzahl, sizeof(DWORD), 1, pFile);
    		for(i = 0; i < Anzahl; i++) 
    		{
    			fread(&Grosse, sizeof(DWORD), 1, pFile);
    			fread(actext, Grosse, 1, pFile);
    			cout<<actext<<"\n";
    		}
    	}
    }
    fclose(pFile);
    

    Eigentlich sollte er die while-Schleife beim widerauslesen nur einmal durchlaufen, da ich ja auch nur einmal einen Chunk AUFGABEN vorher in die Datei geschrieben habe. Wenn ich das jetzt aber ausgeben lasse, durchläuft der die Schleife 2 mal und geht beim 2. Mal auch wieder in die If-Abfrage, ob es sich um eine Aufgabe handelt. Dabei gibt er dann wieder 4 mal den letzten String aus. (Ich habe es vorher mit 4 unterschiedlichen Strings versucht und beim zweiten mal wird nur noch der 4. String 4 Mal ausgegeben)

    Wie kann das sein, weiß jemand den Fehler?

    Vielen Dank für eine Antwort, viele Grüße
    Andreas



  • Hallo,

    das wird wohl daran liegen, dass nach dem erstenmal einlesen eof noch nicht gesetzt wurde. Wenn dann noch einmal eingelesen wirs, wird zwar eof gesetzt, du bist aber schon in der Schleife und in CH steht noch der alte Wert. Machs doch mal so

    while(!feof(pFile))
    {
        //Chunkheader lesen:
        fread(&CH, sizeof(ChunkHeader), 1, pFile);
        if( !feof(pFile))
        {
          cout<<"DRIN";
          if(CH.ChunkTyp == AUFGABEN)
          {
            fread(&Anzahl, sizeof(DWORD), 1, pFile);
            for(i = 0; i < Anzahl; i++)
            {
                fread(&Grosse, sizeof(DWORD), 1, pFile);
                fread(actext, Grosse, 1, pFile);
                cout<<actext<<"\n";
            }
          }
        }
    }
    


  • Du kannst auch fread in die Schleifenbedingung packen. Wenn sich der Rückgabewert von fread vom dritten Parameter (in deinem Fall '1') unterscheidet, dann ist ein Fehler aufgetreten oder das Dateiende wurde erreicht:

    while(fread(&CH, sizeof(ChunkHeader), 1, pFile)==1)
    {
          cout<<"DRIN";
          if(CH.ChunkTyp == AUFGABEN)
          {
            fread(&Anzahl, sizeof(DWORD), 1, pFile);
            for(i = 0; i < Anzahl; i++)
            {
                fread(&Grosse, sizeof(DWORD), 1, pFile);
                fread(actext, Grosse, 1, pFile);
                cout<<actext<<"\n";
            }
          }
    }
    

    Guck dir auch diesen Artikel eventuell nochmal an:
    http://www.cplusplus.com/reference/clibrary/cstdio/fread.html
    Ansonsten würde ich eventuell eher die C++ Filestreams (fstream, ifstream, ofstream) benutzen.

    Greetz



  • Hi vielen Dank für die Antworten, es läuft jetzt



  • Hmm ... schonmal was von File Streams ufm. gehört?


Anmelden zum Antworten