为银行记录创建数据库

时间:2011-12-16 12:28:26

标签: c database

这是我正在处理的项目的代码,我的目标是创建一个数据库,我可以在其中添加编辑和删除记录。该程序正在编译,但非常缓慢,经常崩溃。我只是一个初学者,我无法弄清楚为什么会这样。也许有人可以帮助我改进代码或指出我正确的方向?

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);
            }

2 个答案:

答案 0 :(得分: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;
    }

我知道您依赖的事实是,当您写出列表时,最后编写的结构应该将“next”字段设置为NULL作为结束标记,但我建议您可能希望找到更清洁的方式检查结束。由于您分配了 newa ,但是在最后一次读取时中断,因此最后 newa 永远不会被使用。

此外,加载例程导致列表中的第一条记录为空记录,因为您分配第一,将 currenta 设置为它,然后分配 newa 第一次阅读并将其设置为空 currenta 下一步

加载后,虽然你只有1条记录。请注意,您没有阅读 newa ,而是阅读 currenta

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

您尝试保存数据也存在问题,您有一个典型的拼写错误:

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

您正在为数据文件变量重新分配NULL,您需要 ==

您似乎在整个代码中假设 currenta 是全局的,处于已知状态。例如,在 listAll 功能中,您的代码在打印出记录之前未设置 currenta 。另请注意 listAll 循环并打印所有记录,只打印 currentA ,然后将该变量移动为NULL。

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

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

答案 1 :(得分:0)

printf中存在一个问题:

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

在这里,您使用currenta->number格式说明符打印整数%s,而是使用%d

另一个问题是当您尝试打印列表时:

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

这不是您打印列表的方式。你需要有一个printf作为while循环的主体:

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