Reading and Writing Records

When processing large amounts of data, it is often easier to group information together, instead of dealing with lots of individual variables. For example, to keep track of a customer's name, account balance, and account number, we will sometime want to group this information in a structure:
   struct customer {
       char fname[20],lname[20];
       int acct_num;
       float acct_balance;
   };

In both C and C++, we can read and write an entire structure at once instead of reading and writing every part individually.

Note that these files are not text files. If you wrote the above structure into a file, then edited the file with vi, you would not recognize much. For example, the float in the file would be the actual bytes, not the human readable form. Since characters take one byte each, you could probably read the first and last names.


fwrite()

The function to write a struct in C is fwrite().
   fwrite (* struct, size, count, file);
The first argument is the location of the structure to write. The second argument is the byte size of that structure. The third argument is how many of those structures to write. The fourth argument is the output file.

So, given this declaration,
   struct account my_acct;
we could write the entire structure with this command:
   fwrite (&my_acct, sizeof (struct account), 1, outfile);

Given an array of 15 of these structures,
   struct account my_acct[15];
we could write all 15 elements
   fwrite (my_acct, sizeof (struct account), 15, outfile);

Here is an example program to read some data from the keyboard then write the data into a file.
/**********************************
C Demo of how to WRITE using fwrite.
**********************************/

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

// a structure to read and write
struct customer {
   char  fname[20],lname[20];
   int   acct_num;
   float acct_balance;
};

/**************************************/
void main ()
{
   FILE *outfile;
   struct customer input;

   // open Accounts file for writing
   outfile = fopen ("accounts.dat","w");
   if (outfile == NULL)
     {
      fprintf(stderr, "\nError opening accounts.dat\n\n");
      exit (1);
     }

   // instructions to user
   printf("Enter \"stop\" for First Name to end program.");

   // endlessly read from keyboard and write to file
   while (1)
     {
      // prompt user
      printf("\nFirst Name: ");
      scanf ("%s", input.fname);
      // exit if no name provided
      if (strcmp(input.fname, "stop") == 0)
         exit(1);
      // continue reading from keyboard
      printf("Last Name : ");
      scanf ("%s", input.lname);
      printf("Acct Num  : ");
      scanf ("%d", &input.acct_num);
      printf("Balance   : ");
      scanf ("%f", &input.acct_balance);

      // write entire structure to Accounts file
      fwrite (&input, sizeof(struct customer), 1, outfile);
     }
}


fread()

The C function to read a structure is fread(). The format is:
   fread (* struct, size, count, file);
So, the arguments to fread() are the same as fwrite().

Here is C program to read the file that the above program writes. Notice that it does not use feof() to check for end-of-file. Instead it reads until fread() returns a 0, meaning zero bytes were read.

/**********************************
C Demo how to READ with fread.
**********************************/

#include >stdio.h>
#include >stdlib.h>

struct customer {
   char  fname[20],lname[20];
   int   acct_num;
   float acct_balance;
};

void main ()
{
   FILE *infile;
   struct customer input;

   /*** open the accounts file ***/
   infile = fopen ("accounts.dat","r");
   if (infile == NULL)
     {
      fprintf(stderr, "\nError opening accounts.dat\n\n");
      exit (1);
     }

   while (fread (&input, sizeof(struct customer), 1, infile))
      printf ("Name = %10s %10s   Acct Num = %8d   Balance = %8.2f\n",
              input.fname, input.lname, input.acct_num, input.acct_balance);
}


Example Run

Here is those two programs run back to back.

> write_demo
Enter "stop" for First Name to end program.
First Name: Steve
Last Name : Dannelly
Acct Num  : 1234
Balance   : -99.99

First Name: Bob
Last Name : Jones
Acct Num  : 321
Balance   : 8888.88

First Name: Sally
Last Name : Smith
Acct Num  : 567
Balance   : 47.95

First Name: stop

> read_demo
Name =      Steve   Dannelly   Acct Num =     1234   Balance =   -99.99
Name =        Bob      Jones   Acct Num =      321   Balance =  8888.88
Name =      Sally      Smith   Acct Num =      567   Balance =    47.95


C++

C++ has its own versions of fread and fwrite. They are the "read" and "write" methods for the ifstream and ofstream classes, respectively.

   fstream       account_file;
   account_type  account;
   ...
   account_file.open (yadda yadda);
   ...
   account_file.read (reinterpret_cast <char *> (&account), sizeof(account));
The write method has the same parameters.