No guarda correctamente los datos, fichero binario

Dudas e ideas sobre los distintos e infinitos (:-)) algoritmos existentes.
Responder
Mensaje
Autor
Nishiki
Mensajes: 2
Registrado: 27/03/2019 1:12 am

No guarda correctamente los datos, fichero binario

#1 Mensaje por Nishiki » 02/05/2019 1:28 am

Bueno pues tenemos que crear un fichero binario para guardar los personajes de Juego de Tronos, y no conseguimos que se guarde al cerrarlo y abrirlo de nuevo, y lo muestre. Os dejo el struct que usamos, las funciones de introducir y mostrar. Agradecería vuestra ayuda. :D

Código: Seleccionar todo

typedef struct {
	char nom[MAXLONG], familia[MAXLONG];
	int puntuacio[MAXPUNT];
}tpersona;

void crear(){
	FILE *got;
    got=fopen("got.dat","wb");
    if (got==NULL)
        exit(1);
    fclose(got);
}

void introduir (){
	int i;
	tpersona p;
	if (introduit==0){
		FILE *got;
		got= fopen("got.dat","wb");
		if (got==NULL)   exit(1);
		printf ("Introdueix nom:  ");  gets(p.nom);
		printf ("Introdueix familia:  ");  gets(p.familia);
		for (i=0; i<MAXPUNT; i++){
			printf ("Introdueix puntuacio:  ");  
			scanf ("%d", &p.puntuacio[i]);
		}
		getchar();
		fwrite (&p, sizeof(tpersona), 1, got);
		fclose(got);
		introduit=1;
	}
	else{
		FILE *got;
		got= fopen("got.dat","ab");
		if (got==NULL)   exit(1);
		printf ("Introdueix nom:  ");  gets(p.nom);
		printf ("Introdueix familia:  ");  gets(p.familia);
		for (i=0; i<MAXPUNT; i++){
			printf ("Introdueix puntuacio:  ");  
			scanf ("%d", &p.puntuacio[i]);
		}
		getchar();
		fwrite (&p, sizeof(tpersona), 1, got);
		fclose(got);
	}
}

void llista(){
	tpersona p;
	int i;
	FILE *got;
	got= fopen("got.dat","rb");
	while (!feof(got)){
		fread(&p, sizeof(tpersona), 1, got);
		printf ("%s\n", p.nom);
		printf ("%s\n", p.familia);
		for (i=0; i<MAXPUNT; i++){
			printf ("%d\n", p.puntuacio[i]);
		}
		fread(&p, sizeof(tpersona), 1, got);
	}
	fclose(got);
}
Última edición por mollok el 02/05/2019 6:03 am, editado 1 vez en total.
Razón: Los códigos deben ir entre etiquetas 'code', botón </>

mollok
Mensajes: 468
Registrado: 30/01/2018 9:47 am
Ubicación: Mallorca, España

Re: No guarda correctamente los datos, fichero binario

#2 Mensaje por mollok » 02/05/2019 6:14 am

En llista, en vez de esto

Código: Seleccionar todo

while (!feof(got)){
	fread(&p, sizeof(tpersona), 1, got);
	printf ("%s\n", p.nom);
	printf ("%s\n", p.familia);
	for (i=0; i<MAXPUNT; i++){
		printf ("%d\n", p.puntuacio[i]);
	}
	fread(&p, sizeof(tpersona), 1, got);
}
Pasad a esto:

Código: Seleccionar todo

fread(&p, sizeof(tpersona), 1, got);
while (!feof(got)){
	printf ("%s\n", p.nom);
	printf ("%s\n", p.familia);
	for (i=0; i<MAXPUNT; i++){
		printf ("%d\n", p.puntuacio[i]);
	}
	fread(&p, sizeof(tpersona), 1, got);
}
De vuestra forma, al final del bucle leéis todo un registro que, cuando se repite, lo machacáis con una nueva lectura.

Por otra parte.
A la hora de leer en un disco o de extraer datos no se debe usar toda la estructura sino que hay que pasar sus elementos uno a uno. Cuando un programa acomoda una estructura en memoria puede que no lo haga de la forma en que está programada sino que se intenta acomodarla para que le sea más fácil al ordenador usarla. Uno no sabe cómo está conformada cuando el programa está ejecutando. Así cuándo un programa graba una estructura en disco lo hace tal y como la tiene en la memoria byte a byte. Cuándo se recupere esa estructura del disco en otro momento puede que esté conformada de una forma diferente y, cómo la saca byte a byte, puede que los elementos no concuerden de cómo están en disco a cómo están en la memoria y por tanto veréis 'basura'.

Para evitar esto dad la estructura elemento a elemento, por ejemplo: primero el nombre, después la familia para continuar con cada una de las puntuaciones. A la hora de sacarla del disco debéis leer los elementos en el mismo orden en que fueron guardados: primero el nombre, después la família para terminar con las puntuaciones. Podéis cambiar este orden pero sí se debe mantener que el orden en que habéis guardado los elementos debe ser exactamente el mismo en que lo sacáis.
while(is_alive(yourself)) {
    make_true(yourself, yourdreams);
}

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado