2011-12-16 96 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。你使用过哪个编译器? – 2012-03-15 01:53:36

回答

0

的一个问题是在printf的:

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

这里你正在使用的打印格式%s符整数currenta->number,使用%d来代替。

的另一个问题是,当你试图打印的清单:

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

这不是你如何打印列表。您需要将printf作为while循环的主体:

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,但这样会在最后一次读取时断开,因此从未使用过上次的新的

此外,在第一条记录的负荷常规结果列表是空的记录,因为你分配firsta,设置电流A它,然后分配纽瓦第一个读取,并将其设置为接下来的空currenta

加载后,尽管您只会有1条记录。请注意,你是不是读成纽瓦你读入电流A

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

您试图保存的数据也有一些问题,你有经典的错字错误之一:

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

你正在重新分配NULL到数据文件变量,这里需要==

您似乎假设整个代码是currenta,它是全局的,处于已知状态。例如,在listAll函数中,您的代码在打印出记录之前未设置currenta。还请注意listAll不是循环和打印所有记录,您只打印任何currentA然后将该变量移动到NULL。

我建议你只保留firsta作为一个全局的查找列表的头,但在其他地方使用局部变量并正确设置它们。

如前所述,您的printf语句需要匹配它们的数据类型。这可能会导致失败。