In Lesson 9 of Learn C With Me, we begin one of the most practical topics we’ve encountered so far: File Input/Output in C.
Using Beej’s Guide to C as our study material, we learn how C represents open files using FILE *, how to open and close files, and how to read and write text data using several different standard library functions.
We cover:
- What file input/output means in C
- The
FILE *data type - The concept of streams
- The standard streams
stdin,stdout, andstderr - Why
stdoutandstderrare separate streams - A quick look at shell redirection
- The difference between text and binary streams
- Opening files with
fopen() - Understanding file modes such as
"r","w","a", and their variants - Closing files with
fclose() - Reading individual characters with
fgetc() - Understanding EOF
- Why
fgetc()returns anintinstead of achar - Reading an entire file one character at a time
- Reading text one line at a time with
fgets() - Using a character array as an input buffer
- Understanding the size argument passed to
fgets() - What happens when a line is larger than the buffer
- Working with newline characters read from a file
- Formatted file input with
fscanf() - Reading multiple values from structured text files
- Why
scanf-style functions need to be treated carefully with untrusted input - Limiting string field widths to help avoid buffer overflows
- Opening a file for writing
- How
"w"mode truncates an existing file - Writing individual characters with
fputc() - Writing strings with
fputs() - Writing formatted output with
fprintf()
One of the important ideas in this lesson is that C treats files as streams. The same general model also applies to stdin, stdout, and stderr, which helps explain why functions such as fprintf() can write either to a file or directly to standard output.
We also spend plenty of time experimenting with fgets() and its buffer size. Rather than just accepting the example, we change the size, inspect the results, and work through what actually happens when the buffer isn’t large enough to contain an entire line.
Later, we move on to formatted input with fscanf(), where things get more interesting — and potentially more dangerous. We look at how formatted input can overflow a buffer if we’re careless and why field widths matter when reading strings.
Finally, we turn things around and start writing text files, using fputc(), fputs(), and fprintf() to generate output ourselves.
As usual, we experiment, make predictions, get confused, consult the documentation, make mistakes, get help from the live chat, and try to understand what C is actually doing rather than simply memorizing function calls.
This is Part One of File Input/Output. We stop just before Binary File I/O, which we’ll continue with in the next lesson.
