Problema con programa en C (Programación).

Buenas! No sabia muy bien dónde poner este topic, así que supuse que el mejor sitio quizás seria aquí. Llevo dia y medio dando vueltas a por qué no funciona una cosa en un programa que estoy haciendo, a ver si vosotros me podeis echar una mano, porque estoy desesperado ya :( Copio el codigo:



void  Actualizar_Devolucion (int id_prestamo ) {
   Fecha fecha;
   FILE *FP;
   reg_prestamo rp;
   int encontrado=0;

         /* Genera la fecha de hoy y la almacena en el argumento fecha */
   genera_fecha(fecha);

   if((FP=fopen("prestamos.dat", "ab+"))==NULL) exit(0);

   while(!encontrado && fread(&rp, sizeof(rp), 1, FP))
      if(rp.id_prestamo==id_prestamo)
         encontrado=1;

   if (encontrado==1){   
      strcpy(rp.fecha_devolucion,fecha);
      fwrite(&rp, sizeof(rp), 1, FP);   
   }
   
   fclose(FP);
}



Donde reg_prestamo es una estructura definida como:

typedef struct {
char titulo[100];
char autor[100];
char editorial[100];
NIF NIFcliente;
char apellido1[100];
char apellido2[100];
char nombre[100];
Fecha fecha_prestamo;
} recibo_prestamo;

Y NIF y Fecha son respectivamente cadenas de caracteres:

typedef char Fecha[9];

typedef char NIF[100];

Recorro el archivo prestamos.dat, hasta que el identificador pasado como argumento coincida con alguno del archivo, y si coincide, sobreescribo el valor de fecha_devolucion y lo guardo.

Bien, el problema, que tengo es que al escribir con fwrite no se escribe bien, ya que despues de escribir, he vuelvo a abrir el archivo en modo lectura y lo he recorrido, hasta que el id_prestamo coincida, y la variable fecha_devolucion no almacena el valor de la fecha de hoy. He comprobado que la funcion genera_fecha(fecha); trabaja correctamente, y devuelve la fecha totalmente valida, y si meto un printf entre el strcpy y el fwrite, el atributo rp.fecha_devolucion me muestra la fecha bien, pero despues de escribirla en el archivo me muestra el valor que tenia antes. Ya nose donde está el fallo, y tampoco recurriria a molestar si no estuviese ya cansado de no encontrar el problema.

Muchas gracias por vuestra ayuda :)
Porque tu crees que estás sobreescribiendo los registros que lees. Pero realmente los estás duplicando. Al abrir el fichero con 'a' lo que haces es que todas las escrituras vayan AL FINAL, y no a la posición del cursor. Ábrelo con w+ y listo.

Según ISOC99:

7.19.5.3 párrafo 5:

Opening a file with append mode ('a' as the first character in the mode argument)
causes all subsequent writes to the file to be forced to the then current end-of-file,
regardless of intervening calls to the fseek function. In some implementations, opening
a binary file with append mode ('b' as the second or third character in the above list of
mode argument values) may initially position the file position indicator for the stream
beyond the last data written, because of null character padding.


También puedes mirar aquí http://www.opengroup.org/onlinepubs/009 ... fopen.html

- ferdy
Gracias ferdy, pense en usar wb, pero si hago eso, me cargo el archivo prestamos.dat, y borra los datos que ahi hubiese :(

Edito:

Leo:
r+ or rb+ or r+b
Open file for update (reading and writing).

No sabia que con la opción rb+ también podria escribir en el archivo, voy a probar asi, muchas gracias!

EDITO: Queria haber actualizado el ultimo mensaje, pero se ve que no me deja :( El caso es que creo que tengo un problema con el uso de ficheros, que no acabo de entender como van, he hecho un mini programa que pida el nombre y la edad de 3 personas diferentes, y luego, si uno de los nombres es Javi, cambia su edad a 99 y recorre el fichero para mostrar el nuevo dato.

Codigo:

    typedef struct {
        int edad;
        char nombre[20];
        } t_ficha;
         
int main(){
   
    t_ficha persona;
    FILE *prueba;
    int i;
   
    if((prueba=fopen("prueba.dat", "wb"))==NULL)
       printf("\nError al abrir el archivo");
       /** Introducir los datos en el archivo. */
       for(i=0; i<3; i++){
          printf("\nDame el nombre: ");
          gets(persona.nombre);
          fflush(stdin);
          printf("\nDame la edad: ");
          scanf("%d", &persona.edad);
           fflush(stdin);
          fwrite(&persona, sizeof(persona), 1, prueba);       
       
       }
       fclose(prueba);
       
       /* Actualizacion de los datos */
       if((prueba=fopen("prueba.dat", "rb+"))==NULL)
       printf("\nError al abrir el archivo");       
       
       
       fread(&persona, sizeof(persona), 1, prueba);
       while(feof(prueba)==0){
       if(strcmp(persona.nombre, "Javi")==0){
          persona.edad=99;
          printf("\nEntro por la condicion");
          fwrite(&persona, sizeof(persona), 1, prueba);                   
          }
          fread(&persona, sizeof(persona), 1, prueba);
       }
       fclose(prueba);
       
       /* Lectura de los nuevos datos */
        if((prueba=fopen("prueba.dat", "rb"))==NULL)
       printf("\nError al abrir el archivo");   
       
       fread(&persona, sizeof(persona), 1, prueba);
       while(feof(prueba)==0){
       if(strcmp(persona.nombre, "Javi")==0){
          printf("La nueva edad es: %d", persona.edad);
          }
       fread(&persona, sizeof(persona), 1, prueba);
       }
       
       fclose(prueba);

return 0;
}


Y al hacerlo, me pasa como con mi codigo, que me sigue mostrando la edad que introduje por teclado y no 99, y si que entra por la condicion, porque he escrito un printf y se ejecuta. Algo hay mal y por mas que miro no encuentro el fallo :(:(

Mil gracias!
Obviamente w+ no.... r+

- ferdy

------------

Je, parece que nos estamos pisando las respuestas. Me debes una cerveza.

- ferdy
(mensaje borrado)
4 respuestas