Speicherung einzelner Bytes



  • Guten Abend zusammen 🙂

    Ich habe ein etwas seltsames problem. ich habe eine methode zur speicherung von daten. bisher hat das auch super geklappt, aber jetzt plötzlich, macht er probleme und will das nicht mehr so wirkl. wieder einlesen.

    also ich habe folgende routine:

    void Save() {
    		// Datei leer öffnen
    		file = fopen(dlg.GetPathName(), "wb");
    
                    // Alle Elemente speichern
    		for (curElement = pFirstElement; curElement != NULL; curElement = curElement->nextElement)
    				curElement->SaveToFile(file, &frameRect);
    
    		// Datei schließen
    		fclose(file);
    }
    

    Dann habe ich natürl. noch die Klasse Elements, der curElement angehört:

    //////////////////////////////////////////////////////////////////////
    void CElements::SaveToFile(FILE *pFile, CRect* pFrameRect)
    //
    //////////////////////////////////////////////////////////////////////
    {
    	byte	byteBuffer;
    	short	shortBuffer;
    	char	charBuffer;
    
    	// ChunkID
    	byteBuffer = 2;
    	fwrite(&byteBuffer, 1, 1, pFile);
    
    	// ID des Elementes Speichern
    	byteBuffer = id;
    	fwrite(&byteBuffer, 1, 1, pFile);
    
    	// Type des Elementes
    	byteBuffer = type;
    	fwrite(&byteBuffer, 1, 1, pFile);
    
    	// x- und y-Choords bestimmen (Konvertierung in relative Koordianten)
    	shortBuffer = (short) (boundingRect.left - pFrameRect->left);
    	fwrite(&shortBuffer, 2, 1, pFile);
    	shortBuffer = (short) (boundingRect.top - pFrameRect->top);
    	fwrite(&shortBuffer, 2, 1, pFile);
    
    	// Breite und Höhe des Elementes 
    	shortBuffer = boundingRect.Width();
    	fwrite(&shortBuffer, 2, 1, pFile);
    	shortBuffer = boundingRect.Height();
    	fwrite(&shortBuffer, 2, 1, pFile);
    
    	// RGB-Farbe des Elementes
    	byteBuffer = 0;
    	fwrite(&byteBuffer, 1, 1, pFile); // Rot
    	fwrite(&byteBuffer, 1, 1, pFile); // Grün
    	fwrite(&byteBuffer, 1, 1, pFile); // Blau
    
    	// Anzeigestatus (Anzeigen, Aktivieren)
    	byteBuffer = (show)? 1:0; // Anzeigen
    	fwrite(&byteBuffer, 1, 1, pFile);
    	byteBuffer = (deactive)? 0:1; // Aktivieren
    	fwrite(&byteBuffer, 1, 1, pFile);
    
    	// es folgt (zunächst) direkt der Event-Function-Block
    	// Anzahl der Funktionen
    	shortBuffer = 0;
    	for (int i=0; i<23; i++) 
    	{
    		if (aAction[i]) shortBuffer++;
    	}
    	fwrite(&shortBuffer, 2, 1, pFile);
    
    	// es folgen die einzelnen Funktionsblöcke
    	for (i=0; i<23; i++)
    	{
    		// Überprüfung, ob überhaupt eine Funktion vorliegt
    		if (!aAction[i]) continue;
    
    		// ChunkID
    		byteBuffer = 5;
    		fwrite(&byteBuffer, 1, 1, pFile);
    
    		// Event
    		byteBuffer = (byte)i;
    		fwrite(&byteBuffer, 1, 1, pFile);
    
    		// refID des eigentl. Befehls
    		shortBuffer = (short)aAction[i]->GetRefCmd()->GetID();
    		fwrite(&shortBuffer, 2, 1, pFile);
    
    		// Parameter
    		byteBuffer = aAction[i]->parameters.GetLength();
    		for (int j=0; j<byteBuffer; j++)
    		{
    			charBuffer = aAction[i]->parameters.GetAt(j); 
    			fwrite(&charBuffer, 2, 1, pFile);
    		} // for (int j=0; j<byteBuffer; j++)
    		charBuffer = '#';
    		fwrite(&charBuffer, 2, 1, pFile);
    	}
    
    	// Elementbeschriftung
    	byteBuffer = title.GetLength();
    	for (i=0; i<byteBuffer; i++)
    	{
    		charBuffer = title.GetAt(i); 
    		fwrite(&charBuffer, 2, 1, pFile);
    	} // for (int i=0; i<byteBuffer; i++)
    	charBuffer = '#';
    	fwrite(&charBuffer, 2, 1, pFile);
    
    }
    // void CElements::SaveToFile(FILE *pFile)
    // *******************************************************************
    //////////////////////////////////////////////////////////////////////
    

    Soweit so klar. Nun habe ich noch einen Konstruktor der Klasse CElements, der beim Laden der Datei benutzt wird:

    CElements::CElements(FILE* pFile, CRect* pFrameRect, CElements* pPrevElement, CCommands* listHeader01, CCommands* listHeader02)
    {
    	byte		byteBuffer;
    	short		shortBuffer;
    	char		charBuffer;
    	CPoint		topLeftPoint;
    	CCommands*	refCommand;
    	CString		parameter;
    
    	// allgm. Einstellungen
    	prevElement = pPrevElement; 
    	nextElement = NULL;
    	fixed = false;
    	if (pPrevElement) pPrevElement->nextElement = this; // Vorgängers next-Element aktualisieren
    
    	// Daten aus pFile auslesen
    
    	// ChunkID
    	fread(&byteBuffer, 1, 1, pFile);
    
    	// ID des Elementes 
    	fread(&byteBuffer, 1, 1, pFile);
    	id = byteBuffer;
    	if (id > counter) counter = id;
    
    	// Type des Elementes
    	fread(&byteBuffer, 1, 1, pFile);
    	type = byteBuffer;
    
    	// x- und y-Choords bestimmen (Konvertierung in absolute Koordianten)
    	fread(&shortBuffer, 2, 1, pFile);
    	boundingRect.left = shortBuffer + pFrameRect->left;
    	fread(&shortBuffer, 2, 1, pFile);
    	boundingRect.top = shortBuffer + pFrameRect->top;
    
    	// Breite und Höhe des Elementes 
    	fread(&shortBuffer, 2, 1, pFile);
    	boundingRect.right = boundingRect.left+shortBuffer;
    	fread(&shortBuffer, 2, 1, pFile);
    	boundingRect.bottom = boundingRect.top+shortBuffer;
    
    	// RGB-Farbe des Elementes
    	fread(&byteBuffer, 1, 1, pFile); // Rot
    	fread(&byteBuffer, 1, 1, pFile); // Grün
    	fread(&byteBuffer, 1, 1, pFile); // Blau
    
    	// Anzeigestatus (Anzeigen, Aktivieren)
    	fread(&byteBuffer, 1, 1, pFile);
    	show = (byteBuffer == 1)?true:false;
    	fread(&byteBuffer, 1, 1, pFile);
    	deactive = (byteBuffer == 0)?true:false;
    
    	// es folgt (zunächst) direkt der Event-Function-Block
    	// initial alles NULL
    	for (int i=0; i<23; i++)
    		aAction[i] = NULL;
    
    	// Anzahl der Funktionen
    	fread(&shortBuffer, 2, 1, pFile);
    
    	// es folgen die einzelnen Funktionsblöcke
    	for (i=0; i<shortBuffer; i++)
    	{
    		// ChunkID
    		fread(&byteBuffer, 1, 1, pFile);
    
    		// Event
    		fread(&byteBuffer, 1, 1, pFile);
    
    		// refID des eigentl. Befehls
    		fread(&shortBuffer, 2, 1, pFile);
    
    		// Refernzbefehl auf den ersten der Liste (Selbstdefinierte Befehle) setzen
    		refCommand = listHeader01;
    		if (!refCommand) refCommand = listHeader02;
    
    		while (refCommand->GetID() != shortBuffer) 
    		{
    			if ((!refCommand->next) && (refCommand->commands))
    				refCommand = listHeader02;
    			else if (refCommand) refCommand = refCommand->next;
    		}
    
    		// wenn kein Unterbefehl gefunden wurde => Abbruch
    		if (!refCommand) return;
    
    		// Parameter
    		parameter.Empty();
    
    		fread(&charBuffer, 2, 1, pFile);
    		while (charBuffer != '#')
    		{
    			parameter += charBuffer;
    			fread(&charBuffer, 2, 1, pFile);
    		} // for (int i=0; i<byteBuffer; i++)
    
    		if (refCommand)
    			// es wurde ein "Unterbefehl gefunden mit Parameter
    			aAction[byteBuffer] = new CCommands(refCommand, parameter);
    
    	}
    
    	// Elementbeschriftung
    	for (i=0; i<255; i++)
    	{
    		fread(&charBuffer, 2, 1, pFile);
    		if (charBuffer == '#') break;
    		title += charBuffer;
    	} // for (int i=0; i<byteBuffer; i++)
    
    }
    

    Mein Problem ist jetzt, dass das Speichern bei einer Anzahl von 7 Elementen super funktioniert, aber bei 8 macht er probleme. wobei das irgendwie unterschiedlich ist, denn ich habe auch schon versionen gehabt, wo ich 15 elemente hatte und es funktioniert hat.

    Ich weiß, dass er irgendwann einfach eine schwachsinnige x-/y-Koordinate für die Elemente einliest. Aber ich weiß auch, dass er beim schreiben die richtigen werte zumindest einliest und eigentlich dann auch schreiben müsste.

    Meine Frage daher: Kann das irgendwas mit der art und weise, wie ich speicher zu tun haben? Hab ich die funktionen fread() und fwrite() irgendwie falsch benutzt?

    Schönen Abend noch,
    Hannes



  • du benutzt bei 'fread' und 'fwrite' hardcodierte konstanten für die länge, da können sich schnell fehler einschleichen. nimm besser 'sizeof()'.

    btw: erstmal musste rauskriegen, ob read oder write hakelt. du könntest dir z.b. erstmal ein paar generierte dateien mit einem hexeditor angucken, ob da alles stimmt...



  • Ich hab es *freu*.

    Das Problem war in dem Konstruktor:

    // Anzahl der Funktionen
        fread(&shortBuffer, 2, 1, pFile);
    
        // es folgen die einzelnen Funktionsblöcke
        for (i=0; i<shortBuffer; i++)
        { 
             ....
        }
    

    In der for-Schleife wurde shortBuffer überschrieben 😞
    So ein simpler Fehler... Naja, man lernt nur aus fehlern ^^


Anmelden zum Antworten