2014-12-31 4 views
-1

Теперь функции работают с файлом. Обновлен файл успешно. но когда я печатаю 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(); 
     } 

    } 


} 
+1

Прежде всего, проверка * все * из ваших операций ввода-вывода для достижения успеха, а не предполагая, что они работали. – WhozCraig

+0

Эта строка: 'void updateFile (struct client x, float bal)' должно быть: 'void updateFile (struct client * x, float bal)', затем эта строка: 'fread (& x, sizeof (x), 1, orig) ;» должен быть: 'fread (& x, sizeof (struct client), 1, orig);' и эта строка: 'fwrite (& x, sizeof (x), 1, copy); должен быть: 'fwrite (& x, sizeof (struct client), 1, copy); потому что C передает параметры по значению, а не по ссылке, поэтому данные вызывающих абонентов не обновляются текущим кодом – user3629249

+0

Да, они работают. – imagineracoon

ответ

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 
+0

Убрать все равно будет? Когда я использую функцию снятия после того, как она говорит о успехе, она закрывается. – imagineracoon

+0

Я не дал вам (возможных) исправлений для отзыва(). в надежде, что вы сможете внести какие-либо исправления, учитывая пример того, как это сделать в функции updateFile(). Позвольте мне взглянуть на функцию вывода() и вернуться к вам. – user3629249

+0

его нормально я понимаю. – imagineracoon

-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(); 
} 
+1

Я заметил, что «ACCOUNT» был капитализирован в некоторых местах в размещенном коде и в нижнем регистре в других. капитализация должна быть такой же, как фактическое имя файла – user3629249

Смежные вопросы