Click for Table of Contents
The C Primer
Book and Reference Collection
Copyright © 2024 by Rance D. Necaise
Table Of Contents
The C Primer
Copyright © 2024
Rance D. Necaise

6.4 File Processing

Reading data from a text file that is then examined or manipulated in some way is known as file processing. When reading a collection of data or processing the contents of a file, we need a properly constructed input loop:

   // priming read
  while( condition ) {
     //process data
     //modification read
  }

Remember, the condition in the input loop tests for or compares against the sentinel value, which indicates that we have finished reading data or reached the end of the input collection.

End of File

When reading and processing a file, the sentinel value is typically a test to determine if the end of file has been reached. In C, the feof function is used for this purpose

   // priming read
  while( !feof(infile) ) {
     . . .
    // modification read
  }

The feof returns true if the end of file was reached during the last input operation (i.e. using either fscanf or fgetc). Note, that you must first try reading data from the input file before testing if the end of file was reached. Thus, the need for a priming read.

Processing Data

Consider a text file that contains a set of exam grades specified as integers stored one per line

  85
  90
  89
  75
  100
  98
  86

Suppose we want to compute the average exam grade for a collection of grades stored in a text file. This task can be accomplished using the following code segment:

  int grade;
  int sum = 0;
  int count = 0;

  fscanf(infile, "%d", &grade);     // priming read
  while(!feof(infile)) {            // test for end of file
    sum = sum + grade;
    count = count + 1;
    fscanf(infile, "%d", &grade);   // modification read
  }

  float avg = sum / float(count);
  printf("Average exam grade = %0.2f\n", avg);

Sometimes, the text file may contain records of information in which each record contains multiple fields of information. For example, suppose the data file contained both the id number and the exam grade for each student in the following format:

  245 85
  189 90
  175 89
  206 75
  122 100
  284 98
  111 86

Since each record consists of two fields, only the first field has to be read before testing for the end of file. He we would read the student id number as the priming read, then test for the end of file. If the end of file was not reached, we then read the rest of the record before processing the data. These steps are illustrated in the following code segment:

  int grade, id;
  int sum = 0;
  int count = 0;

  fscanf(infile, "%d", &id);       // priming read - read first record field (id num)
  while(!eof(infile)) {
    fscanf(infile, "%d", &grade);  // read the rest of the record
    sum = sum + grade;
    count = count + 1;
    fscanf(infile, "%d", &id);     // modification read
  }

Remember, the modification read should always be the same operation as the priming read. Thus, we only read the id number at the bottom of the loop.

Processing Characters

Sometimes, you may want to read the text from the file as characters instead of numerical data. The fscanf function, however, as indicated in the previous section, skips over white space characters when reading individual characters from the file. If you need to read all characters, including white space characters, then you must use the fgetc function instead of the fscanf function. The fgetc function takes the file variable as an argument and returns the next character in the file without skipping over any other characters

  int ch;
  ch = fgetc(infile);

This function is typically used within a loop to read multiple characters from a text file. In the following program, we read the individual characters from the text file and simply display them to the terminal.

Program Listing
 
Program: showfile.cc
  1. /* showfile.cc
  2.  *
  3.  * Reads the contents of a text file and prints the contents to the terminal.
  4.  */
  5.  
  6. #include <stdio.h>
  7.  
  8. int main()
  9. {
  10.   FILE *infile;
  11.  
  12.    // Open the file and verify it was opened.
  13.   infile = fopen("document.txt", "r");
  14.   if(!infile) {
  15.     printf("Error: the input file could not be opened.\n");
  16.     exit(1);
  17.   }
  18.  
  19.    // Read the entire contents and print it to the terminal.
  20.   int ch;
  21.  
  22.   ch = fgetc(infile);           // priming read
  23.   while(!feof(infile)) {        // test for end of file
  24.     printf("%c", ch);
  25.     ch = fgetc(infile);         // modification read
  26.   }
  27.  
  28.    // Close the file
  29.   fclose(infile);
  30. }
Page last modified on March 17, 2025, at 09:04 AM