Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Write two functions, which read/write an array of accounts to/from a file. Write

ID: 3852278 • Letter: W

Question

Write two functions, which read/write an array of accounts to/from a file. Write driver code to test the two functions. The driver code and the test output must show clearly that the file input and output work correctly.

Requirements:

Definition of Account

Create a header file, account.h, containing the following definition.
Note that the structure is different from that in the previous assignments.

struct account
{
    char         name[25];
    int          accountno;
    float        balance;

}; // This semicolon is important!!!

Read/Write Functions

Create a source file, iofunctions.c, containing the following functions.

int readfile( struct account accarray[ ], int * numcust, char filename[ ] );
int writefile( struct account accarray[ ], int numcust, char filename[ ] );

Basic specifications

The function, readfile, will read the data from a text file and store it in the array specified by accarray.
It must tell the function which called it how many accounts it has stored into the array.

The function, writefile, will write the data stored in the array specified by accarray into a text file.

The return values will be used to tell whether the functions successfully read/write data.

The size of the array and the name of the text file are assumed to be arbitrary (You cannot specify them in this file).

The functions must not have user I/O (printf, scanf, etc).

Driver Code

Define the following local variables in the main function:

struct account bankone[5];
int numcustomers;

A menu is not required. The user-interface can be very simple, but the output of the program must be clear and self-explanatory and must be definitive proof that the functions work.

You may get input from the keyboard or hardcode your array in the driver for testing.

The driver code must be written in different c file(s) rather than iofunctions.c.

Explanation / Answer

driver.c


#include "ioheader.h"
#include <stdio.h>
#include <string.h>


int main(int argc, char* argv[])
{
    struct account bankone[5];
    int numcustomers;
    int customer = 0;
    int accnoTestCount = 1;
    float balanceTestCount = 1.00;
    int errorcheck = 13;

    printf(" ***Tests of writefile*** ");
    printf(" Test when filename is missing.");
    printf(" Should return -1 which means error. ");

    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Name");
        bankone[customer].accountno = accnoTestCount;
        bankone[customer].balance = balanceTestCount;
        balanceTestCount++;
        accnoTestCount++;
    }
    accnoTestCount = 1;
    balanceTestCount = 1.00;

    numcustomers = 5;
    errorcheck = writefile(bankone, numcustomers, "");

    if (errorcheck == -1)
    {
        printf("Error, %d returned ", errorcheck);
        errorcheck = 5;
    }
    else
    {
        printf("Returned %d", errorcheck);
        errorcheck = 5;
    }

    printf(" Test when file is not a .txt file");
    printf(" Should return -1 which means error. ");

    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Name");
        bankone[customer].accountno = accnoTestCount;
        bankone[customer].balance = balanceTestCount;
        balanceTestCount++;
        accnoTestCount++;
    }
    accnoTestCount = 1;
    balanceTestCount = 1.00;

    numcustomers = 5;
    errorcheck = writefile(bankone, numcustomers, "badfile.t");

    if (errorcheck == -1)
    {
        printf("Error, %d returned ", errorcheck);
        errorcheck = 5;
    }
    else
    {
        printf("Returned %d", errorcheck);
        errorcheck = 5;
    }

    printf(" Test of writing an invalid number of records.");
    printf(" Should return -1 which means error. ");

    numcustomers = 0;
    errorcheck = writefile(bankone, 0, "InvalidTest.txt");

    if (errorcheck == -1)
    {
        printf("Error, %d returned ", errorcheck);
        errorcheck = 5;
    }
    else
    {
        printf("Returned %d", errorcheck);
        errorcheck = 5;
    }

    printf(" Test of adding a single record,");
    printf(" the output file is called test1rec.txt ");

    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Name");
        bankone[customer].accountno = accnoTestCount;
        bankone[customer].balance = balanceTestCount;
        balanceTestCount++;
        accnoTestCount++;
    }
    accnoTestCount = 1;
    balanceTestCount = 1.00;

    numcustomers = 1;
    errorcheck = writefile(bankone, numcustomers, "test1rec.txt");

    if (errorcheck == -1)
    {
        printf("Error, %d returned ", errorcheck);
        errorcheck = 5;
    }


    printf(" Test of adding 5 records to an empty file,");
    printf(" the output file is called test5rec.txt ");

    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Name");
        bankone[customer].accountno = accnoTestCount;
        bankone[customer].balance = balanceTestCount;
        balanceTestCount++;
        accnoTestCount++;
    }
    accnoTestCount = 1;
    balanceTestCount = 1.00;

    numcustomers = 5;
    errorcheck = writefile(bankone, numcustomers, "test5rec.txt");

    if (errorcheck == -1)
    {
        printf(" Error, %d returned ", errorcheck);
        errorcheck = 5;
    }

    printf(" ***Test of readfile***");
    printf(" From here, if any output says 'Readfile didn't work', then");
    printf(" the function isn't working. ");
    printf(" Test when filename is invalid. Should return -1 on error. ");

    errorcheck = readfile(bankone, &numcustomers, "NonExistantFile.txt");

    if (errorcheck == -1)
    {
        printf("Error, %d returned ", errorcheck);
        errorcheck = 5;
    }
    else
    {
        printf("Returned %d", errorcheck);
        errorcheck = 5;
    }

    printf(" Test when filen is not a .txt file");
    printf(" Should return -1 which means error. ");

    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Name");
        bankone[customer].accountno = accnoTestCount;
        bankone[customer].balance = balanceTestCount;
        balanceTestCount++;
        accnoTestCount++;
    }
    accnoTestCount = 1;
    balanceTestCount = 1.00;

    numcustomers = 5;
    errorcheck = readfile(bankone, &numcustomers, "badfile.t");

    if (errorcheck == -1)
    {
        printf("Error, %d returned ", errorcheck);
        errorcheck = 5;
    }
    else
    {
        printf("Returned %d", errorcheck);
        errorcheck = 5;
    }

    printf(" Test of reading a single record,");
    printf(" 1 record will be read from test1rec.txt ");

    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Readfile didn't work.");
        bankone[customer].accountno = 999;
        bankone[customer].balance = 999.999;
    }

    readfile(bankone, &numcustomers, "test1rec.txt");

    for (customer = 0; customer < numcustomers; customer++)
    {

        printf("%s %d %f ", bankone[customer].name,
        bankone[customer].accountno,
        bankone[customer].balance);
    }

    printf(" Test of reading 5 records from a file that contains 5 records.");
    printf(" 5 records will be read from test5rec.txt ");
    for (customer = 0; customer < 5; customer++)
    {
        strcpy(bankone[customer].name, "Readfile didn't work.");
        bankone[customer].accountno = 999;
        bankone[customer].balance = 999.999;
    }

    readfile(bankone, &numcustomers, "test5rec.txt");

    for (customer = 0; customer < numcustomers; customer++)
    {
        printf("%s %d %f ", bankone[customer].name,
        bankone[customer].accountno,
        bankone[customer].balance);
    }

return 0;
}


account.h

struct account
{
    char        name[25];
    int         accountno;
    float       balance;
};


iofunctions.c


#include "ioheader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*****************************************************************
//
// Function name: readfile
//
// DESCRIPTION: Function that reads records from a file into a provided
//              array of records. The record has parameters name (char[])
//              accountno (int), and balance (float). Will stop when
//              the end of the file has been reached. The file must be a .txt
//              file.
//
//
// Parameters: accarray (account []): array of records to be filled.
//              numcust (int*) : Pointer to number of customers in file.
//              filename (char[]) : Name of file to be read from.
//
// Returns : 0 on successful read.
//          -1 if file not found.
//
//****************************************************************/

int readfile(struct account accarray[], int* numcust, char filename[])
{
    char line[80];
    int customer = 0;
    int returnvalue = 0;
    FILE *filepointer;

    *numcust = 0;

    if (filename[strlen(filename)-4] == '.' &&
        filename[strlen(filename)-3] == 't' &&
        filename[strlen(filename)-2] == 'x' &&
        filename[strlen(filename)-1] == 't')
    {
        filepointer = fopen(filename, "r");
    }
    else
    {
        filepointer = NULL;
    }

    if (filepointer != NULL)
    {
        while (feof(filepointer) == 0)
        {

            fgets(line, 80, filepointer);

            if (feof(filepointer) == 0)
            {
                if (line[strlen(line) - 1] == ' ')
                {
                    line[strlen(line) - 1] = '';
                }

                strcpy(accarray[customer].name,line);

                fgets(line, 80, filepointer);

                if (line[strlen(line) - 1] == ' ')
                {
                    line[strlen(line) - 1] = '';
                }
                accarray[customer].accountno = atoi(line);

                fgets(line, 80, filepointer);

                if (line[strlen(line) - 1] == ' ')
                {
                    line[strlen(line) - 1] = '';
                }

                accarray[customer].balance = atof(line);

                customer++;
                *numcust = *numcust + 1;

            }

        }
        fclose(filepointer);
    }
    else
    {
        returnvalue = -1;
    }
    return returnvalue;
}

/*****************************************************************
//
// Function name: writefile
//
// DESCRIPTION: Writes data from provided records to the specified file.
//              Will create a file if file does not exist.
//              If file aleady exists, it overwrites the file.
//              The file must be a .txt file.
//
// Parameters: accarray (account[]) : The array of records to be written.
//              numcust(int) : the number of records to be added.
//              filename (char[]) : The name of the file to write to.
//
// Retunrs: 0 : on successful write.
//          -1 : if write is unsuccesful for any reason such as
//               invalid number of customers.
//
//****************************************************************/

int writefile(struct account accarray[], int numcust, char filename[])
{
    int customer = 0;
    int returnvalue = 0;

    FILE *filepointer;

    if (filename[strlen(filename)-4] == '.' &&
        filename[strlen(filename)-3] == 't' &&
        filename[strlen(filename)-2] == 'x' &&
        filename[strlen(filename)-1] == 't')
    {
        filepointer = fopen(filename, "w");
    }
    else
    {
       filepointer = NULL;
    }

    if (filepointer != NULL)
    {
        if (numcust > 0)
        {

            for (customer = 0; customer < numcust; customer++)
            {
                fprintf(filepointer,"%s %d %f ", accarray[customer].name,
                accarray[customer].accountno, accarray[customer].balance);

            }

            fclose(filepointer);
        }
        else
        {
            returnvalue = -1;
            fclose(filepointer);
        }
    }
    else
    {
        returnvalue = -1;

    }

    return returnvalue;
}

ioheader.h


#include "account.h"
int readfile(struct account accarray[], int* numcust, char filename[]);
int writefile(struct account accarray[], int numcust, char filename[]);