Book
Collection
Click for Table of Contents
© 2025 by Rance D. Necaise
C Primer for Python Programmers
Copyright © 2025
Rance D. Necaise

6.5 Processing Records

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. Here 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:

  1.   int grade, id;
  2.   int sum = 0;
  3.   int count = 0;
  4.  
  5.   fscanf(infile, "%d", &id);       // priming read - read first record field (id num)
  6.   while(!eof(infile)) {
  7.     fscanf(infile, "%d", &grade);  // read the rest of the record
  8.     sum = sum + grade;
  9.     count = count + 1;
  10.     fscanf(infile, "%d", &id);     // modification read
  11.   }

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.

Worked Example

Now consider a more detailed problem in which the text file contains three exam grades for each student in the following format:

  245 85 70 90
  189 90 87 92
  175 89 98 92
  206 75 70 81
  122 100 98 99
  284 98 90 86
  111 86 65 71

The objective is to compute the average exam grade for each individual student and produce a report similar to the following:

 Id #  Avg Grade
----------------
 245       81.67
 189       89.67
 175       93.00
 206       75.33
 122       99.00
 284       91.33
 111       74.00

In solving this problem, we must compute the average grade for each student based on the scores for three exams. In the previous example, there was a single grade per student, which could be read as the first statement within the while loop.

After reading the first id number and testing to make sure we have not reached the end of file, we will need to read the three exam grades using a loop. Here we use a for loop (and assume sum was previously declared as an integer):

  1. sum = 0;
  2. for(int i = 0; i < 3; i++) {
  3.   fscanf(infile, "%d", &grade);
  4.   sum = sum + grade;
  5. }

Once all of the grades have been read and summed, we can now compute the average grade for the student (where avg is a floating-point variable):

  1. avg = sum / 3.0;    

To complete the processing of the record, next we print the results for the current student:

  1. printf("%4d   %9.2f\n", id, avgGrade);

After printing the results, we need to read the next id number as the modification read. This process continues until all of the records have been read and processed. In a well-designed program, these steps would be placed within a separate function that can be called after opening and verifying the file.

A complete solution for this problem is provided in the program listing below. Take time to review the source code as it also illustrates a top-down design and the use of functions in such a design.

Listing
  1. /* procgrades.cc
  2.  *
  3.  * Read records of data from a text file that contains the exam grades for a group
  4.  * of students along with their id number. The program reads the records of data,
  5.  * computes the average exam grade for each student and prints a report to
  6.  * standard output.
  7. */
  8.  
  9. #include <stdio.h>
  10.  
  11. void printRecord(int id, float avgGrade);
  12. void processGrades(FILE *infile);
  13.  
  14.  
  15. int main()
  16. {
  17.   FILE *infile;
  18.  
  19.    /* Open the file and make sure it's valid. */
  20.   infile = fopen("examgrades.txt", "r");
  21.   if(!infile) {
  22.     printf("Error: The input file can not be opened.\n");
  23.     return 1;
  24.   }
  25.  
  26.    /* Print the report header. */
  27.   printf(" Id #  Avg Grade\n");
  28.   printf("----------------\n");
  29.  
  30.    /* Otherwise, process the data. */
  31.   processGrades(infile);
  32.  
  33.    /* Close the file. */
  34.   fclose(infile);
  35. }
  36.  
  37.  
  38. void processGrades(FILE *infile)
  39. {
  40.   int grade, id;
  41.   int sum = 0;
  42.   float avg;
  43.  
  44.    // Read the first student id number.
  45.   fscanf(infile, "%d", &id);      
  46.   while(!feof(infile)) {
  47.    
  48.      // Read and the three exam grades and total the values.
  49.     sum = 0;
  50.     for(int i = 0; i < 3; i++) {
  51.       fscanf(infile, "%d", &grade);
  52.       sum = sum + grade;
  53.     }
  54.    
  55.      // Compute the average exam grade.
  56.     avg = sum / 3.0;
  57.    
  58.      // Print the results.
  59.     printRecord(id, avg);
  60.    
  61.      // Read the next student id number
  62.     fscanf(infile, "%d", &id);  
  63.   }  
  64. }
  65.  
  66.  
  67. void printRecord(int id, float avgGrade)
  68. {
  69.   printf("%4d   %9.2f\n", id, avgGrade);
  70. }
Program: procgrades.cc