Skip to content
Physics and Astronomy
Home Our Teaching Resources C programming A complete example
Back to top

Input and Output: a larger example for you to study

Let's pull a few of these concepts together by writing a program that reads some integers from the screen, stopping when it reads a value of zero, and for each value prints that value and the square of that value to a file.

The program then opens that file for reading and checks that it does indeed contain a list of integers, each followed by its square.

Since writing and reading the file are separate, self-contained tasks we make each a separate functions.

The original is a single file but we split it into three parts for readability.

The program header and the main() function

/* 
 * Demonstrate writing to, and reading from a file.
 * We do this by reading some integers from the keyboard
 * and writing them, and their squares, to a file.
 * After closing the file, we read integers and their squares, 
 * back in again, checking the squares are correct 
 */
#include <stdio.h>
#include <stdlib.h>

void write_data();
void read_and_check_data();

int main() {
  write_data();
  read_and_check_data();

  return 0;
}

The only things to notice here are the inclusion of stdlib.h for exit(), and the function prototypes.

Reading input from the terminal and writing the file

/*
 * Read integers from standard input and write the
 * integers and their sqaures to a file. 
 * Exit the program on failure.
 */
void write_data() {
  FILE *outfile;

  outfile = fopen("mydata.txt", "w");
  if ( outfile == NULL ) {
    fprintf(stderr, "I cannot write to the data file\n");
    exit(1);
  }

  printf("Please enter one integer per line. Enter zero to stop\n");

  /* loop until the input value is zero */
  while( 1 == 1 ) {
    int i;

    printf("Next value? (zero quits)  ");
    scanf("%d", &i);

    if ( i == 0 )
      break;

    fprintf(outfile, "%d %d\n", i, i * i);
  }

  fclose(outfile);
}

First we open the output file, exiting the program if that fails, with a warning to stderr. Notice we exit with a non-zero value (1) to indicate the programmed failed to run successfully.

Then we have an infinite loop, breaking out of it when the input is zero and writing each input integer and its square to the output file. Although it's not critical, we declared the variable i inside the loop's { ... } block as it is never used outside of it.

Finally we close the output file using fclose(). This is important as otherwise the data might not be written as C is allowed to buffer output for efficiency (i.e. to save up output until a reasonable amount needs to be written and then write it all at once).

C provides the "file flush" function fflush(outfile) to flush any buffered data to disk even before the file is closed.

Read in the file and check it is correct

/* 
 * Read integers and their squares, checking the squares are correct 
 * Exit the program on failure.
 */

void  read_and_check_data() {
  int i, isquared;
  FILE *infile;

  infile = fopen("mydata.txt", "r");
  if ( infile == NULL ) {
    fprintf(stderr, "I cannot read from the data file\n");
    exit(2);
  }

  /* Carry on as long as we can read two integers from the file */
  while ( fscanf(infile, "%d %d", &i, &isquared) == 2 ) {
    if ( isquared != i * i ) {
      fprintf(stderr, "The ivalues %d and %d disagree!\n",
        i, isquared);
      exit(3);
    }
    
    printf("%d squared is %d\n", i, isquared);
  }
  fclose(infile);
}

First we open for reading the file we have just written. Notice we use "r" as the second argument to fopen() not "w". As before, if the open fails we write a message to stderr and exit, using a different non-zero value (2).

We then enter a classic loop for reading from a file: we try to read in two integers, i and isquared. The call to fscanf() is inside the control expression of the while loop: the value returned by fscanf(), which is equal to the number of data values it has successfully read in, is compared to see if it equal to two. If it isn't, the loop quits.

If the data values disagree we print an error message and exit, this time with the value 3.

One subtle point that's worth noticing is that we print a positive confirmation that we have read in some valid input. It is much better to print a message when we are sure something is correct than when we are sure something is wrong. It's always possible for a program to find new ways of going wrong!

Finally, we close the input file.

                                                                                                                                                                                                                                                                       

Validate   Link-check © Copyright & disclaimer Privacy & cookies Share
Back to top