We Have a Lot on File on You

Earlier, we saw how an array of structures can be used to represent a table. Often we want such tables to be in files as well. The fread() and fwrite() calls can do that for us. By reading or writing more than one structure, integer or any other data type we can read and write whole arrays of data at once.

Consider again the video store example. We'll write two functions that will provide the file handling for this program. The first function will be called at the beginning of the program's execution. It will read a file of video structures into an array and return the number of structures that were read. This number will be the number of videos that we carry in our store.


int load_videos(char name[], struct video list[], int max_videos)
{
   FILE *fp;
   int num;
   fp = fopen(name, "rb");
   if(fp == NULL)
      return -1;
   num = fread(list, sizeof(struct video), max_videos, fp);
   fclose(fp);
   return num;
}

Here we see another feature of fread() . It returns the number of items that were read. In this case, we will read the maximum number unless there were fewer in the file. The actual number read will be the number of items we have in our array now. This is the number of videos in our store. If there was an error opening the file, then we'll return -1 so that the calling function will know that an error has occurred.

Now we turn our attention to the function we'll call before exiting the program. This function will save the videos back to the file. Otherwise, it will be the same as our load_videos() function.


int save_videos(char name[], struct video list[], int num_videos)
{
   FILE *fp;
   fp = fopen(name, "wb");
   if(fp == NULL)
      return -1;
   fwrite(list, sizeof(struct video), num_videos, fp);
   fclose(fp);
   return 0;
}

Again we see that we'll return a -1 to inform the calling function of an error.

While we won't study it here, there are some other things we can do to files. For example, we can ask how big a file is and then allocate (with malloc() ) an array to hold the whole thing. We can also move around within the file to random positions so that we update specific parts of the file.


Consider the following program:
#include <stdio.h>
#define MAX 100
main()
{
   FILE *fp;
   int list[MAX], n, i;
   fp = fopen("file1", "rb+");
   n = fread(list, sizeof(int), MAX, fp);
   for(i = 0; i < n; ++i)
      list[i] *= list[i];
   fwrite(list, sizeof(int), n, fp);
   fclose(fp);
}
If file1 has the numbers 3 and 5 in it before the program is run, what will be the contents of the file after?

3 5

9 25

3 9 5 25

3 5 9 25