DeePyson
DeePyson

Reputation: 11

Trouble writing/reading struct array in a binary file in C

I am trying to make a program that stores the name, employee number and salary of employees in a database, where I have to then store the amount of employees along with all the information of each employee (name, number, salary). I need to store the information in a binary file named "EMPLOYEE.DAT". The function PersistEmployees() runs at the end of the program when the user is finished putting employee information, and is the one that stores the information. There is another function named RestoreEmployees(), which I will explain later. Both functions are in a separate file.

Here is PersistEmployees();

void PersistEmployees(struct Employees employees[], int numOfEmployees)
{
    FILE* fout;
    fout = fopen("EMPLOYEE.DAT", "wb+");

    if (!fout)
    {
        fprintf(stderr, "Error opening file EMPLOYEE.DAT\n");
        exit(1);
    }

    fwrite(&numOfEmployees, sizeof(numOfEmployees), 1, fout);
    fwrite(employees, sizeof(struct Employees) * numOfEmployees, 1, fout);

    fclose(fout);
}

Here is a screenshot of the "EMPLOYEE.DAT" file that gets created

Then, when the program runs again, "EMPLOYEE.DAT" is to be read, and the program gets the number of employees, stored in an int variable, and the information of each employee, which is stored in a struct array. The function, named RestoreEmployees, takes one parameter, a struct array, and returns the number of employees read.

Here is RestoreEmployees();

int RestoreEmployees(struct Employees employees[])
{
    int employeesInDatabase = 0;

    FILE* fin;
    fin = fopen("EMPLOYEE.DAT", "rb+");

    if (!fin)
    {
        return 0;
    }

    fread(&employeesInDatabase, sizeof(int), 1, fin);
    fclose(fin);

    return employeesInDatabase;
}

The number of employees gets returned properly, 1 when there is only 1 stored, 2 when there is 2, but the struct array is just a jumble of random characters.

Here is the struct that stores the information:

struct Employees
{
    int employeeNumber;
    char name[100];
    double salary;
};

I'm currently thinking it's something with reading the file, but I'm not sure. Please don't be too harsh as reading and writing files in c is very confusing to me lol.

Upvotes: 1

Views: 94

Answers (1)

Diego Ferruchelli
Diego Ferruchelli

Reputation: 874

I'll expand on what has already been answered in the comments to your question.

  1. You're missing a fread() call at the end of RestoreEmployees(). Compare your own code: two calls to fwrite(), but just one call to fread(). The missing line would be something like:
    fread(employees, sizeof(struct Employees) * numOfEmployees, 1, fin);
  1. You should check the return of the fwrite() and fread() calls. In this case, you're requesting to write/read just one big "element" (the third parameter in each call), and the result will be 0 (nothing write/read, check errno) or 1 (done OK).

  2. Please, remember that local (volatile) variables aren't automatically initialized to default values in C/C++. The "jumble of random characters" you see are probably whatever already was in the memory positions assigned to the elements of the Employees[] array. By the way, remember that you need to allocate space (one way or another) for all the elements in the array.

  3. The C language specification establishes a minimum size for the (signed or unsigned) char, short int and long int types, and also for the default (plain) int type and the floating point types. The exact size is implementation dependant (usually, platform dependant). If you intend to transfer your file(s) between different platforms, it's better to use a clearly defined fixed width format. The C99 specifications includes some pseudo-types (typedefs) for this, like uint16_t, for "unsigned integer of 16 bits".

  4. Related to the previous point, the size_t pseudo-type is defined by each implementation in <stddef.h> as an integer wide enough to contain the size of the widest possible variable/array/memory structure. You can see this in the definition/prototype of fwrite(), etc.

Upvotes: 4

Related Questions