modificar dato de un fichero

minette1988
10 de Abril del 2010
Hola, el enunciado dice así:

La compañía telefónica tiene un fichero que guarda las facturas correspondientes a sus abonados; se desea un programa en C para gestionarlo. Las operaciones serán:

- alta de nuevas facturas.
- Buscar una ficha y modificar la factura.
- facturación total o de un solo abonado.
- Borrar fichero.

Este es el programa:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*LEE_CAD permite escribir los nombres con espacios en blanco*/
#define LEE_CAD(c,n) { int i=0;
c[i]=getchar();
while((c[i]=='n') || (c[i]=='t')) c[i]=getchar();
while((c[i]!='n') && (i < (n-1))){
i++;
c[i]=getchar();}
c[i]='';}

#define LEE_CAR(c)
c=getchar();
while((c==' ')||(c=='n')||(c=='t'))
c=getchar();


typedef struct{
char tel[10];
char nom_completo[100];
float fact;
}abonado;

void alta_fact(FILE *);
void modif_fich(FILE *);
void mostrar_todo(FILE *);
float fact_total(FILE *);
float fact_uno(FILE *);

int main(){
char op;
FILE *pf;

if((pf=fopen("fact_telefon.dat", "ab+")) == NULL){
fprintf(stderr, "Error Fichero y salirn");
exit(1);}

do{
printf("a--> Altanb--> Buscar/Modificar fichant--> Factura totalnf--> Factura abonadonm--> Mostrar todo el ficheron");
printf("x--> Borrar fichero y salirnElija opcion(s--> Salir): ");
LEE_CAR(op);

switch(op){
case 'a':
case 'A':{alta_fact(pf); break;}
case 'b':
case 'B':{modif_fich(pf); break;}
case 't':
case 'T':{printf("n%s %.2lfn", "La factura total es de:", fact_total(pf)); break;}
case 'f':
case 'F':{printf("n%s %.2fn", "La factura es de:", fact_uno(pf)); break;}
case 'm':
case 'M':{mostrar_todo(pf); break;}
case 'x':
case 'X':{fclose(pf); pf=NULL; remove("fact_telefon.dat"); op= 's'; break;}
}
}while((op != 's') && (op != 'S'));
if(pf != NULL)
if(fclose(pf) == EOF)
fprintf(stderr, "Error al cerrar el fichero de ejer_fichero3_secn");
exit(0);
}

void alta_fact(FILE * d){
abonado cliente;

printf(" Num de telefono del abonado: ");
scanf("%9s", cliente.tel);
printf("Nombre completo: ");
LEE_CAD(cliente.nom_completo, 100);
printf("Valor de la factura: ");
scanf("%f", &cliente.fact);
fwrite(&cliente,sizeof(cliente),1,d);
}

void modif_fich(FILE * d){
char op;
char tel[10];
abonado cl;
int comp;
FILE * aux;/*Fichero auxiliar por si modifica la ficha del abonado*/

if((aux=fopen("fact_telefon.aux", "wb+")) != NULL){
printf("Telefono del abonado a buscar/modificar: ");
scanf("%9s", tel);
rewind(d);
fread(&cl,sizeof(cl),1,d);
comp=strcmp(cl.tel, tel);
while((comp != 0) && (!feof(d))){
fwrite(&cl,sizeof(cl),1,aux);
fread(&cl,sizeof(cl),1,d);
comp=strcmp(cl.tel, tel);}
if(comp == 0){
printf("Abonado encontrado:n");
printf("%sn%sn%.2fn", cl.nom_completo, cl.tel, cl.fact);
printf("Modificar factura (s/n)?");
LEE_CAR(op);
if((op == 's') || (op == 'S')){
printf("Valor de la factura: ");
scanf("%f", &cl.fact);
fwrite(&cl,sizeof(cl),1,aux);
fread(&cl,sizeof(cl),1,d);
while(!feof(d)){
fwrite(&cl,sizeof(cl),1,aux);
fread(&cl,sizeof(cl),1,d);}
if(fclose(aux) == EOF)
fprintf(stderr, "Error al cerrar el fichero auxiliar de ejer_fichero3_secn");
remove("fact_telefon.dat");
rename("fact_telefon.aux", "fact_telefon.dat");
if((d=fopen("fact_telefon.dat", "ab+")) == NULL){
fprintf(stderr, "Error al cerrar el fichero de ejer_fichero3_secn");
exit(2);}
}
else{
if(fclose(aux) == EOF)
fprintf(stderr, "Error al cerrar el fichero auxiliar de ejer_fichero3_secn");
}
}
else{
printf("Abonado no encontradon");
if(fclose(aux) == EOF)
fprintf(stderr, "Error al cerrar el fichero auxiliar de ejer_fichero3_secn");
}
}
}

float fact_total(FILE * d){
abonado cl;
float total=0.0;
rewind(d);/*Pone el puntero al principio del fichero*/
fread(&cl,sizeof(cl),1,d);
while(!feof(d)){
total+=cl.fact;
fread(&cl,sizeof(cl),1,d);
}
return(total);
}

float fact_uno(FILE * d){
char tel[10];
abonado cl;
int comp;
float total;

printf("Telefono del abonado a facturar: ");
scanf("%9s", tel);
rewind(d);/*Pone el puntero al principio del fichero*/
fread(&cl,sizeof(cl),1,d);
comp=strcmp(cl.tel, tel);
while((comp != 0) && (!feof(d))){
fread(&cl,sizeof(cl),1,d);
comp=strcmp(cl.tel, tel);
}
if(comp == 0)
total=cl.fact;
else{
printf("Abonado no encontradon");
total = -1;
}
return(total);
}

void mostrar_todo(FILE * d){
abonado cl;

rewind(d);
fread(&cl,sizeof(cl),1,d);
while(!feof(d)){
printf("%st%st%.2fnn", cl.tel, cl.nom_completo, cl.fact);
fread(&cl,sizeof(cl),1,d);
}
}

Cuando lo compilo y me pregunte ¿Modificar factura? pongo que sí, a continuación cambio el valor de la factura, pero cuando pongo la opción de facturar un cliente me sale el valor de la factura inicial no la modificada. Cuando pongo la opción mostrar todo, es decir todos los registros, me sale la factura inicial del cliente no la nueva.

trasgu
10 de Abril del 2010
-En la función "modif_fich" el archivo "fact_telefon.dat" no se puede borrar porque está en uso debes cerrarlo antes de borrarlo:
if(fclose(d) == EOF)
fprintf(stderr, "Error al cerrar el fichero de ejer_fichero3_secn");

-Otro error es que el programa permite introducir registros iguales.