现在功能正在处理文件。成功更新了文件。但是当我打印x.curbal
时
例如printf("Current Balance: %.2f\n",x.curbal);
它会打印旧值。但是当我关闭程序并再次打开它时,会打印新值。
void updateFile(struct client x, float bal)
{
FILE *orig;
FILE *copy;
orig = fopen("ACCOUNT.txt","r");
fread(&x,sizeof(x),1,orig);
/*fscanf(orig,"%s %s %s %s %f",x.accnum,x.accode,x.fname,x.lname,x.curbal);*/
x.curbal = bal;
copy = fopen("temp.txt","w");
fwrite(&x,sizeof(x),1,copy);
/*fprintf(copy,"%s %s %s %s %f",x.accnum,x.accode,x.fname,x.lname,x.curbal);*/
fclose(orig);
fclose(copy);
remove("account.txt");
rename("temp.txt","account.txt");
}
void withdraw(struct client x)
{
FILE *fp;
FILE *orig;
FILE *copy;
float debit = 0;
float withdrawal;
fp = fopen("history.txt","a+");
if (fp!=NULL)
{
printf("====WITHDRAW====\n");
printf("Date: %s\n",currdate);
printf("Time: %s\n",currtime);
printf("Name: %s,%s\n",x.lname,x.fname);
printf("Account Number: %s\n",x.accnum);
printf("Current Balance: %.2f\n",x.curbal);
printf("Withdrawal Amount: Php ");
scanf("%f",&withdrawal);
if((s.curbal-withdrawal) < 0)
{
clrscr();
system("cls");
printf("Transaction Failed.\n\n");
printf("Insufficient Funds!!!\n\n");
getch();
}
else
{
x.curbal = x.curbal - withdrawal;
clrscr();
updateFile(x,x.curbal);
fprintf(fp,"%s %s %s %.2f %.2f\n",x.accnum,histdate,currtime,debit,withdrawal);
printf("Transaction Completed.\n\n");
printf("Php %.2f was deducted.\n\n",withdrawal);
printf("Remaining Balance: Php %.2f\n\n\n",x.curbal);
getch();
}
}
}
答案 0 :(得分:0)
the following code
-compiles cleanly
-actually updates the callers' data
-has the appropriate error checking
-properly handles the file open operations
-eliminates the compiler generated calls to memcpy()
that result from passing the whole struct
(which C does by value, not as a reference)
so use a pointer to the struct
then the compiler will not generate calls to memcpy()
Note: the code really has to perform error checking
because 'things happen', like wrong permissions,
and I/O errors, that result in failures
#include <stdio.h>
#include <stdlib.h>
struct client
{
float curbal;
};
// prototypes
void updateFile( struct client*, float );
// use pointer to x so callers' data gets updated
void updateFile(struct client* x, float bal)
{
FILE *orig; // input file
FILE *copy; // output file
if( NULL == (orig = fopen("ACCOUNT.txt","r")) ) // "r" will start at the beginning of the file
{ // then fopen failed
perror( "fopen failed for account.txt" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
if( 1 != fread(&x,sizeof(struct client),1,orig) )
{ // then fread failed
perror( "fread of struct client failed" );
exit( EXIT_FAILURE );
}
// implied else, fread successful
/*fscanf(orig,"%s %s %s %s %f",x.accnum,x.accode,x.fname,x.lname,x.curbal);*/
x->curbal = bal;
if( NULL == (copy = fopen("temp.txt","w") ) ) // "w" to write a new file, not append to existing file
{ // then, fopen failed
perror( "fopen failed for temp.txt" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
if( 1 != fwrite(&x,sizeof(x),1,copy) )
{ // then fwrite failed
perror( "fwrite of struct client failed" );
exit( EXIT_FAILURE );
}
// implied else, fwrite successful
/*fprintf(copy,"%s %s %s %s %f",x.accnum,x.accode,x.fname,x.lname,x.curbal);*/
fclose(orig);
fclose(copy);
if( 0 != remove("ACCOUNT.txt") ) // this is C, capitalization counts
{ // then, remove failed
perror( "remove for ACCOUNT.txt failed" );
exit( EXIT_FAILURE );
}
// implied else, remove successful
if( 0 != rename("temp.txt","ACCOUNT.txt") )
{ // then, rename failed
perror( "rename from temp.txt to ACCOUNT.txt failed" );
exit( EXIT_FAILURE );
}
// implied else, rename successful
} // end function: updateFile
答案 1 :(得分:-1)
This is the complete code
note that the original code did not compile
for several reasons including 's' is not defined
// clrscr() is documented to be in stdio.h, but my system does not have it there
// so I used system("cls")
#include <stdio.h>
#include <stdlib.h>
struct client
{
char accnum[100];
char histdate[10];
char currtime[26];
float debit;
float withdrawal;
float curbal;
char lname[30];
char fname[30];
};
// prototypes
void updateFile( struct client*);
void withdraw( struct client* );
// use pointer to x so callers' data gets updated
void updateFile(struct client* x)
{
FILE *orig; // input file
FILE *copy; // output file
if( NULL == (orig = fopen("ACCOUNT.txt","r")) ) // "r" will start at the beginning of the file
{ // then fopen failed
perror( "fopen failed for account.txt" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
if( 1 != fread(&x,sizeof(struct client),1,orig) )
{ // then fread failed
perror( "fread of struct client failed" );
exit( EXIT_FAILURE );
}
// implied else, fread successful
if( NULL == (copy = fopen("temp.txt","w") ) ) // "w" to write a new file, not append to existing file
{ // then, fopen failed
perror( "fopen failed for temp.txt" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
if( 1 != fwrite(&x,sizeof(x),1,copy) )
{ // then fwrite failed
perror( "fwrite of struct client failed" );
exit( EXIT_FAILURE );
}
// implied else, fwrite successful
/*fprintf(copy,"%s %s %s %s %f",x.accnum,x.accode,x.fname,x.lname,x.curbal);*/
fclose(orig);
fclose(copy);
if( 0 != remove("ACCOUNT.txt") ) // this is C, capitalization counts
{ // then, remove failed
perror( "remove for ACCOUNT.txt failed" );
exit( EXIT_FAILURE );
}
// implied else, remove successful
if( 0 != rename("temp.txt","ACCOUNT.txt") )
{ // then, rename failed
perror( "rename from temp.txt to ACCOUNT.txt failed" );
exit( EXIT_FAILURE );
}
// implied else, rename successful
} // end function: updateFile
// use getchar() which requries #include stdio.h
// getch() is a DOS int24 function
// which requires #include <conio.h>
//void withdraw(struct client x) // pass parameter as pointer, as previously discussed
void withdraw( struct client* x )
{
FILE *fp = NULL;
//FILE *orig = NULL; // compiler will output warning about unused varible
//FILE *copy = NULL; // compiler will output warning about unused variable
//float debit = 0; // compiler will output warning about unused variable
float withdrawal = 0.0f;
if( NULL == (fp = fopen("history.txt","a+") ) )
{ // then, fopen failed
perror( "fopen history.txt failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
printf("====WITHDRAW====\n");
//printf("Date: %s\n",currdate); // not defined in scope of posted code
//printf("Time: %s\n",currtime); // not defined in scope of posted code
printf("Name: %s,%s\n",x->lname,x->fname);
printf("Account Number: %s\n",x->accnum);
printf("Current Balance: %.2f\n",x->curbal);
printf("Withdrawal Amount: Php ");
if( 1 != scanf("%f",&withdrawal) )
{ // then, scanf failed
perror( "scanf withdrawal failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
//if((s.curbal-withdrawal) < 0) // 's' not declared
if((x->curbal-withdrawal) < 0.0f) // it is a float value so use '0.0f' to compare
{ // then, not enough funds available
// use one or the other, I suggest using system("cls")
//clrscr();
system("cls");
printf("Transaction Failed.\n\n");
printf("Insufficient Funds!!!\n\n");
}
else
{ // else, enough funds available
x->curbal -= withdrawal;
//clrscr();
system("cls");
updateFile(x);
fprintf( fp,"%s %s %s %.2f %.2f\n",
x->accnum,
x->histdate,
x->currtime,
x->debit,
x->withdrawal );
printf("Transaction Completed.\n\n");
printf("Php %.2f was deducted.\n\n",withdrawal);
printf("Remaining Balance: Php %.2f\n\n\n",x->curbal);
} // end if
fclose( fp ); // cleanup
getchar();
}