[ Foro de C ]

Problema con fseek

18-May-2012 14:30
Antonio Rodriguez
4 Respuestas

Hola de nuevo

Tengo un problema con el fuente del ejercicio de la agenda, y por más que lo intento no lo localizo.

Aclaro que estoy usando W7 y DevC++ v5.2.0.0 como compilador.

El fuente es el siguiente:


/*Ejercicio 6.13
Ampliar el programa anterior (el array de structs con 10 personas) para que el dato
que indique el usuario se lea sin leer y descartar antes los que le preceden, sino que se
salte directamente a la ficha deseada usando "fseek"*/

#include <stdio.h>
#include <stdlib.h>/*necesario para usar la funcion exit(1)*/

main()
{
FILE *fichero;
int x=3; /* Tamaño del struct, uso 3 para que no sea muy
pesado meter los datos*/
struct{
char nombre[50];
int edad;
char ciudad[50];
}datos[x];
int i; /*para contadores*/
int ficha; /*para la ficha que pide consultar el usuario*/

/*Pedimos todos los datos, almacenando el struct en la memoria*/
printf("Entra los siguientes datos:\n");
for (i=0; i<x; i++) {
printf("%d Nombre: ", i+1);
gets (datos[i].nombre);
printf("Edad: ");
scanf("%d", &datos[i].edad);
getchar();
printf("Ciudad de residencia: ");
gets(datos[i].ciudad);
}

/*grabamos todos los datos en el fichero, uso el modo "w" ya que entiendo que
el fichero ha de crearse nuevo cada vez que se ejecuta el programa y se piden los datos*/
fichero = fopen("gente3.dat", "wb");
if(fichero == NULL) {
  printf("No se ha podido abrir/crear el fichero");
  exit(1);
}
fwrite(&datos, sizeof(datos), 1, fichero); /*así se escribe todo el struct de una sola vez*/
fclose(fichero);

/*pedimos el  numero de la ficha a mostrar*/
printf("Escribe el numero de la ficha a mostrar: ");
scanf("%d", &ficha);
getchar();

/*comprobamos que la ficha exista*/
if ((ficha<1)||(ficha>x)) {
do {
printf("Ficha inexistente, intentalo de nuevo: ");
scanf("%d", &ficha);
getchar();
} while ((ficha<1)||(ficha>x));
}

do{
i=ficha-1; /*restamos 1, ya que la primera ficha es la 0*/
fichero = fopen("gente3.dat", "rb"); /*abrimos el fichero como lectura*/
if(fichero == NULL) {
  printf("No se ha podido abrir/crear el fichero");
  exit(1);
}
fseek(fichero, i, 0); /*vamos a la ficha indicada por el usuario*/
fread(&datos, sizeof(datos), 1, fichero); /*leemos todos los datos de la ficha*/
fclose(fichero); /*cerramos el fichero*/
printf("Los datos almacenados son los siguientes: \n");
/*Sacamos por pantalla la ficha pedida*/
printf("Nombre: %s Edad: %d  Ciudad de residencia: %s\n", datos[i].nombre, datos[i].edad, datos[i].ciudad);
/*volvemos a empezar el bucle*/
printf("Escribe el numero de los datos a mostrar: ");
scanf("%d", &ficha);
getchar();
if ((ficha<0)||(ficha>x)) {
do {
printf("Ficha inexistente, intentalo de nuevo: ");
scanf("%d", &ficha);
getchar();
} while ((ficha<0)||(ficha>x));
}
} while (ficha!=0); /*salida del programa*/
printf ("Cerrando el programa...");
}



El programa compila y funciona bien, el problema surge al mostrar las fichas: la ficha nº1 la muestra bien, pero al mostrar la ficha nº 2 lo hace a partir del 2º carácter, corriendo todos los datos un carácter; en la ficha nº 3 muestra a partir del 3º caracter y así sucesivamente. ¿dónde tengo el error?

Gracias por adelantado!


18-May-2012 19:07
bruno zelaia montero

Has probado a abrirlo con los permisos +rb ?
a mi me daba el mismo problema y lo solucioné abriendo con ese permiso...si no recuerdo mal pq hace tiempo que lo hice...pruebalo...


18-May-2012 19:33
Antonio Rodriguez

Hola Bruno!

Me temo que ese no es el problema, al abrirlo en modo "r+b" sigue haciendo lo mismo.

Gracias de todas formas ;)


19-May-2012 11:52
Nacho Cabanes (+83)

A ver...
Tienes un problema en el "fseek":

fseek(fichero, i, 0); /*vamos a la ficha indicada por el usuario*/

Eso no se mueve a la ficha "i", sino al byte "i", de modo que no lees la ficha 2, sino la ficha 1 a partir de su segundo byte. Como sabes el tamaño de cada ficha ("sizeof(datos)"), la posición de cada ficha será 0*sizeof(datos), 1*sizeof(datos), 2*sizeof(datos) y así sucesivamente:

fseek(fichero, i * sizeof(datos), 0);


19-May-2012 14:21
Antonio Rodriguez

Perfecto Nacho, lo he entendido y el programa funciona correctamente, muchas gracias!






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)