2011-12-16 14 views
3

これは私が取り組んでいるプロジェクトのコードです。私の目的は、編集やレコードの追加ができるデータベースを作成することです。プログラムはコンパイルされていますが、非常にゆっくりとしばしばクラッシュします。私は単なる初心者です。なぜこれが起こっているのか理解できません。誰かがコードを改善したり、正しい方向に向けるのを手伝ってくれるかもしれませんか?銀行レコードのデータベースを作成する

enter code here 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 

void clearInput(void); 
void listAll (void); 
void deleteAccount(void); 
void addNewAccount(void); 
void modifyAccount(void); 
int prompt(void); 

struct account{ 
int number; 
char lastname[15]; 
char firstname[15]; 
float balance; 
struct account*next; 
}; 

struct account *firsta, *currenta, *newa; 
int anum = 0; 

int main() 
{ 
FILE *datafile; 
char *filename="studentdatabase.txt"; 
char ch; 
firsta=NULL; 
datafile=fopen(filename, "r"); 
if (datafile) /*assume doesnt exist otherwise*/ 
    { 
    firsta=(struct account*)malloc(sizeof(struct account)); 
    currenta=firsta; 
    while (1) 
     { 
      newa=(struct account*)malloc(sizeof(struct account)); 
      fread(currenta, sizeof(struct account),1,datafile); 
      if (currenta->next==NULL) 
        break; 
       currenta->next=newa; 
     } 
    fclose(datafile); 
    anum=currenta->number; 
    } 
     do 
      { 
       clearInput(); 
       puts("\nA - Add a new account"); 
       puts("D - Delete account"); 
       puts("L - List all accounts"); 
       puts("M - Modify account"); 
       puts("Q - Quit this program\n"); 
       printf("\tYour Choice:"); 
       ch=getchar(); 
       ch=toupper(ch); 
       switch(ch) 
        { 
        case 'A': 
        puts("Add new account\n"); 
        clearInput(); 
        addNewAccount(); 
        break; 

        case 'D': 
        puts("Delete account\n"); 
        deleteAccount(); 
        break; 

        case 'L': 
        puts("List all accounts\n"); 
        listAll(); 
        break; 

        case 'M': 
        puts("Modify an account\n"); 
        modifyAccount(); 
        break; 

        case 'Q': 
        puts ("Quit\n"); 
        default: 
        break; 
        } 
      } 
       while(ch!='Q'); 
       /*Save the records to disc*/ 
       currenta=firsta; 
       if(currenta==NULL) 
        return(0);  /*No data to write - End of Program*/ 
       datafile=fopen(filename,"w"); 

       if (datafile=NULL) 
        { 
         printf("Error writing to %s\n", filename); 
         return(1); 
        } 
        /*write each record to disc*/ 

        while(currenta!=NULL) 
        { 
        fwrite(currenta, sizeof(struct account),1,datafile); 
         currenta=currenta->next; 
        } 
        fclose(datafile); 
        return(0); 
       } 
       /*This function clears any text from the input stream*/ 
       void clearInput(void) 
       { 
        fflush(stdin); 
       } 
       void addNewAccount(void) 
       { 
        newa=(struct account*)malloc(sizeof(struct account)); 
        /*Check to see if this is the first record, if so then 
        itialize all the pointers to this, first ftrusture in 
        the database*/ 
        if(firsta==NULL) 
         firsta=currenta=newa; 
        /*Otherwise you must find the end of the structure list 
        (easily spotted by the NULL pointer) and add on the new 
        structure you just allocated memory for*/ 
        else 
        { 
         currenta=firsta; /*makes the first current*/ 

              /*loop throught all records*/ 
         while(currenta->next!=NULL) 
          currenta=currenta->next; 
          /*last record found*/ 
          currenta->next=newa; /*save the address of new*/ 
          currenta=newa; /*makes current new*/ 
        } 
        /*now you just fill in the new structure*/ 
         anum++; 
         printf("%27s:%5i\n","Account number", anum); 
         currenta->number=anum; 
         printf("%27s:","Enter customer's lastname"); 
         gets(currenta->lastname); 
         printf("%27s:","Enter firstname"); 
         gets(currenta->firstname); 
         printf("%27f:€","Enter account balance"); 
         scanf("%f", &currenta->balance); 
         /*Finally cap the new record with a NULL pointer so 
         that you know its the last record*/ 
         currenta->next=NULL; 
       } 

       void listAll(void) 
       { 
       if (firsta==NULL) 
        puts("There are no records to print out"); 
        else 
        { 
        printf("%6s %-15s %-15s €%8.2f\n", 
         currenta->number, 
         currenta->lastname, 
         currenta->firstname, 
         currenta->balance); 
        } 
        while ((currenta=currenta->next) !=NULL); 
       } 
       void deleteAccount(void) 
       { 
        int record; 
        struct account *previousa; 
        if(firsta==NULL) 
        { 
         puts("There are no records to delete"); 
         return; 
        } 
        listAll(); 
        /*Shows all record first*/ 
        printf("Enter account number to delete: "); 
        scanf("%d",&record); 

        currenta=firsta; 
        while(currenta!=NULL) 
        { 
        { 
        if(currenta->number==record) 
         { 
         if(currenta==firsta) /*special condition*/ 
         firsta=currenta->next; 
         else 
         previousa->next=currenta->next; 
         free(currenta); 
         printf("Account %d deleted! \n", -record); 
         return; 
         } 
         previousa=currenta; 
         currenta=currenta->next; 
        } 
       } 
       printf("Account %d was not found!\n", record); 
       puts("Nothing deleted."); 
       } 
       void modifyAccount(void) 
       { 
       int record; 
       if (firsta==NULL) 
       { 
        puts("There are no records to modify!"); 
        return; 
       } 
      listAll(); /*Show all records first*/ 
      printf("Enter account number to modify or change: "); 
      scanf("%d",&record); 
      currenta=firsta; 
      while (currenta!=NULL) 
      { 
       if(currenta->number==record) 
        { 
        printf("Account €%d:\n", currenta->number); 
        printf("Last name: %s\n", currenta->lastname); 
        if (prompt()) 
         gets (currenta->lastname); 
         printf("firstname %s \n", currenta->firstname); 
        if (prompt()) 
         gets(currenta->firstname); 
         printf("Balance %8.2f\n", currenta->balance); 
        if (prompt()) 
         scanf("%f", &currenta->balance); 
         return; 
        } 
        else 
        { 
        currenta=currenta->next; 
        } 
      } 
      printf("Account %d was not found!\n", record); 
      } 
      int prompt(void) 
      { 
      char ch; 
      clearInput(); 
      printf("Update?"); 
      ch=getchar(); 
      ch=toupper(ch); 
      clearInput(); 
      if(ch=='Y') 
      { 
       printf("Enter new. "); 
       return(1); 
      } 
      else return(0); 
      } 
+0

私はそのコードをコンパイルして実行しました。私はgccを使いました。どのコンパイラを使用しましたか? –

答えて

0

一つの問題は、printf関数である:ここでは

printf("%6s %-15s %-15s €%8.2f\n", 
        currenta->number,... 

あなたの代わりに%dを使用し、%s書式指定子を使用して整数currenta->numberを印刷しています。あなたがリストを印刷しようとしているとき

もう一つの問題は、次のとおりです。

printf(...); 
while ((currenta=currenta->next) !=NULL); 

これは、あなたがリストを印刷する方法はありません。あなたはwhileループの本体としてprintfを持つ必要があります:

while (currenta != NULL) { 
    printf(...); 
    currenta = currenta->next; 
} 
1

最初の入力ループは少し奇妙に見えます。

while (1) 
    { 
     newa=(struct account*)malloc(sizeof(struct account)); 
     fread(currenta, sizeof(struct account),1,datafile); 
     if (currenta->next==NULL) 
       break; 
      currenta->next=newa; 
    } 

私はあなたがリストを書いたとき書き込まれた最後の構造は、あなたのエンドマーカーとしてNULLに設定し、「次へ」のフィールドを持っているはずという事実に依存していることを理解し、私はあなたが欲しいかもしれないことをお勧め終わりをチェックするためのよりクリーンな方法を見つける。 newaを割り当ててから最後の読み込みを中断してから、最後にnewaが使用されることはないので、メモリリークも少なくなります。また

、空のレコードであること、リスト内の最初のレコードのロードルーチンの結果、あなたはfirstaを割り当てるので、それにcurrentaを設定し、その後、最初の読み取りのためにネバを割り当て、に設定次の空のカレント

読み込んだ後、あなたは1レコードしか持っていません。

datafile=fopen(filename,"w"); 
if (datafile=NULL)   
      ^^^ 

:あなたはデータを保存するためにあなたの試みはまた、あなたが古典的なタイプミスのエラーのいずれかを持って、問題がありcurrenta

fread(currenta, sizeof(struct account),1,datafile); 

に読み込まネバに読んでいないことに注意してくださいデータファイルにNULLを再割り当てする場合は、==が必要です。

グローバルであるの最新のは、既知の状態であることを前提としています。たとえば、listAll関数では、レコードを印刷する前にコードがの最新のに設定されていません。またlistAllではないすべてのレコードをループして印刷すると、のcurrentAがNULLになるように移動します。

firstaは、リストの先頭を見つけるためのグローバルとしてのみ使用することをお勧めしますが、それ以外の場合はローカル変数を使用して正しく設定します。

前述のように、printfステートメントはデータ型と一致する必要があります。それは失敗を引き起こす可能性があります。

関連する問題