Reading a File

Once a file is open, we might want to read input from it. There are three common functions in C for reading from a file: fgetc, fgets, and fread. Here’s a breakdown of how fgetc works:

Prototype:

int fgetc(FILE * stream);

Common Issue in Loops:

When reading characters in a loop, beginners often encounter issues because fgetc advances the stream’s position with each call. Consider this incorrect code:

//broken
FILE * f = fopen(inputfilename, "r");
if (f == NULL) { /* error handling code omitted */ }
while (fgetc(f) != EOF) {
  char c = fgetc(f);
  printf("%c", c);
}

Correct Approach:

To fix this, we can leverage the fact that assignment is also an expression, meaning it both assigns a value and evaluates to that value. This allows us to combine the assignment and the EOF check in one line:

//fixed
FILE * f = fopen(inputfilename, "r");
if (f == NULL) { /* error handling code omitted */ }
int c;
while ( (c = fgetc(f)) != EOF ) {
  printf("%c", c);
}

Here’s what happens:

Why int Instead of char?

The variable c is declared as an int, not a char. If we used char, our code would introduce a subtle bug: