[C] problema nell'inserire struct in un file

di il
5 risposte

[C] problema nell'inserire struct in un file

Salve, ho scritto questo codice che teoricamente avrebbe dovuto salvare 3 struct in un file e poi avrebbe dovuto leggerle. Purtroppo gli output sono diversi da quelli sperati e non riesco a capirne i motivi.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

struct salvataggio{
	char risposta[50];
	bool pieno;
};

int main (){

	FILE *fsave; //file dei salvataggi
	int j; //numero dell'indice

	struct salvataggio *salva=malloc(sizeof(struct salvataggio));

	//prima struct
	strcpy(salva->risposta,"ugo");//do un valore ai componenti della struct
	salva->pieno=1;
	fsave=fopen ("salvataggi", "wb");
	fseek(fsave, 0*sizeof(salva), SEEK_SET); //metto il puntatore sulla prima struct
	fwrite(salva, sizeof(struct salvataggio), 1, fsave);
	fclose (fsave);

	//seconda struct
	strcpy(salva->risposta,"gigio");
	salva->pieno=1;
	fsave=fopen ("salvataggi", "wb");
	fseek(fsave, 1*sizeof(salva), SEEK_SET);
	fwrite(salva, sizeof(struct salvataggio), 1, fsave);
	fclose (fsave);

	//terza struct
	strcpy(salva->risposta,"cavallo");
	salva->pieno=1;
	fsave=fopen ("salvataggi", "wb");
	fseek(fsave, 2*sizeof(salva), SEEK_SET);
	fwrite(salva, sizeof(struct salvataggio), 1, fsave);
	fclose (fsave);

	//lettura della prima struct
	fsave=fopen ("salvataggi", "rb");
	fseek(fsave, 0*sizeof(salva), SEEK_SET);
	j=ftell(fsave)/sizeof(salva);
	printf ("%d)", j+1);
	fread(salva, sizeof(struct salvataggio), 1, fsave);
	printf ("...%s...%d\n", salva->risposta, salva->pieno);
	fclose (fsave);

	//lettura della seconda struct
	fsave=fopen ("salvataggi", "rb");
	fseek(fsave, 1*sizeof(salva), SEEK_SET);
	j=ftell(fsave)/sizeof(salva);
	printf ("%d)", j+1);
	fread(salva, sizeof(struct salvataggio), 1, fsave);
	printf ("...%s...%d\n", salva->risposta, salva->pieno);
	fclose (fsave);

	//lettura della terza struct
	fsave=fopen ("salvataggi", "rb");
	fseek(fsave, 2*sizeof(salva), SEEK_SET);
	j=ftell(fsave)/sizeof(salva);
	printf ("%d)", j+1);
	fread(salva, sizeof(struct salvataggio), 1, fsave);
	printf ("...%s...%d\n", salva->risposta, salva->pieno);
	fclose (fsave);

	system("PAUSE");
	return 0;
}
Io mi aspetto come output:

1)...ugo...1
2)...gigio...1
3)...cavallo...1

ma quelli che ottengo sono:

1)......58
2)......62
3)...cavallo...1

Ho notato che risulta giusto solo l'ultimo output. Infatti quando ho eliminato le parti di codice riguardanti la scrittura e la lettura della terza struct gli output sono stati:

1)......62
2)...gigio...1

Vi prego di darmi una mano.
Grazie in anticipo.

5 Risposte

  • Re: [C] problema nell'inserire struct in un file

    1) Per la scrittura utilizza "ab" per le open

    2) Non utilizzare le fseek per le scritture

    3) Non usare sizeof(salva) ma sizeof(struct salvataggio)
  • Re: [C] problema nell'inserire struct in un file

    Ok grazie. ma cosa devo usare allora al posto di fseek se dovessi aver bisogno di scrivere qualcosa in una struct che si trova in mezzo al file?
  • Re: [C] problema nell'inserire struct in un file

    Penso di aver risolto aprendo il file con "rb+", poi puntando ad un determinato indirizzo con fseek e a questo punto usando fwrite. così sembra funzionare, ma non vorrei che fosse solo una coincidenza. mi confermate che è un metodo valido?
  • Re: [C] problema nell'inserire struct in un file

    Fwrite avanza già in automatico il puntatore alla fine del file, per cui se devi scrivere le struct una di seguito all'altra non serve proprio la fseek.
    Se invece vuoi gestire un file ad accesso diretto (in cui leggi o scrivi l'N-esima struct), un modo molto elegante consiste nel mappare il file in memoria (vedi mmap() in linux o CreateFileMapping() + MapViewOfFile() in windows); in questo modo puoi trattare il file come se fosse un array del tipo che vuoi tu (quindi ad esempio un array di struct).
  • Re: [C] problema nell'inserire struct in un file

    little_lakes ha scritto:


    Penso di aver risolto aprendo il file con "rb+", poi puntando ad un determinato indirizzo con fseek e a questo punto usando fwrite. così sembra funzionare, ma non vorrei che fosse solo una coincidenza. mi confermate che è un metodo valido?
    Se è una coincidenza a me dura da oltre 20 anni
Devi accedere o registrarti per scrivere nel forum
5 risposte