CornucopiaBeebee
CornucopiaBeebee

Reputation: 31

Creating a database for bank records

This is my code for a project I'm working on, my aim is to create a database where i can add edit and delete records. The program is compiling but very slowly and often crashes. I am a mere beginner and I cant figure out why this is happening. Maybe somebody can help me improve the code or point me in the right direction?

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

Upvotes: 3

Views: 1792

Answers (2)

Jere
Jere

Reputation: 601

Your input loop in the start looks a bit odd to me.

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

I understand that you are relying on the fact that when you wrote out the list the last structure written should have had the 'next' field set to NULL as your end marker, but I would suggest you might want find a cleaner way to check for end. This will also have a small memory leak since you allocate newa but then break on the last read, so that last newa is never used.

Also, the load routine results in the first record in the list being an empty record because you allocate firsta, set currenta to it, then allocate newa for the first read and set it to the next of the empty currenta.

After loading, though you will only ever have 1 record. Notice that you are not reading into newa you read into currenta

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

Your attempt to save the data also has an issue, you have one of the classic typo errors:

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

you are reassigning NULL to the datafile variable, you need == here.

You appear to assume through out the code that currenta, which is global, is in a known state. For example, in the listAll function, your code is not setting currenta before printing out a record. Note also listAll is not looping and printing all records, you print only whatever currentA is then move that variable to being NULL.

I would suggest you keep only firsta as a global to locate the head of the list, but everywhere else you use local variables and set them up correctly.

As previously mentiond, your printf statements need to match their data types. That can cause failures.

Upvotes: 1

codaddict
codaddict

Reputation: 455360

One problem is in the printf:

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

Here you are printing an integer currenta->number using %s format specifier, use %d instead.

Another problem is when you are trying to print the list:

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

This is not how you print the list. You need to have a printf as the body of the while loop:

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

Upvotes: 0

Related Questions