Um momento
0xD0Lesson 14 of 15

Working with files

Open, read and write files with the FILE API, and handle the errors that real files throw at you.

14 min 5-question quiz 1 code exercise
By the end of this lesson you can
  • Open and close files with fopen and fclose
  • Read line by line with fgets and write with fprintf
  • Handle errors when a file cannot be opened

Programs become useful when their data outlives them. C works with files through a FILE * - a pointer to an object that tracks an open file. You have already been using three of them without knowing it: stdin, stdout and stderr are FILE * values that are opened for you.

Opening and closing

write_notes.c
1#include <stdio.h>
2
3int main(void) {
4    FILE *file = fopen("notes.txt", "w");
5    if (file == NULL) {
6        perror("notes.txt");
7        return 1;
8    }
9
10    fprintf(file, "Buy milk\n");
11    fprintf(file, "Learn pointers\n");
12
13    fclose(file);
14    return 0;
15}

fopen(path, mode) returns a FILE *, or NULL if the file could not be opened (missing file, no permission, bad path). The common modes:

| Mode | Meaning | | --- | --- | | "r" | read an existing file | | "w" | write - creates the file, or erases an existing one | | "a" | append to the end, creating the file if needed |

perror prints your message plus the reason the last call failed (for example, notes.txt: No such file or directory). fclose flushes anything still buffered and releases the file - always close what you open.

Reading line by line

fgets(buffer, size, file) reads one line at a time and returns NULL at the end of the file, which makes a clean loop. Because stdin is a FILE * too, a function that takes a FILE * works on real files and on typed input - which is exactly how the exercises here run.

number_lines.c
1#include <stdio.h>
2
3void number_lines(FILE *input) {
4    char line[256];
5    int number = 1;
6    while (fgets(line, sizeof line, input) != NULL) {
7        printf("%3d | %s", number, line);
8        number++;
9    }
10}
11
12int main(int argc, char *argv[]) {
13    if (argc < 2) {
14        number_lines(stdin);
15        return 0;
16    }
17    FILE *file = fopen(argv[1], "r");
18    if (file == NULL) {
19        perror(argv[1]);
20        return 1;
21    }
22    number_lines(file);
23    fclose(file);
24    return 0;
25}

This program also shows command-line arguments: main(int argc, char *argv[]) receives the words typed after the program name. ./number_lines notes.txt makes argv[1] the string "notes.txt". With no argument, it reads standard input instead - a very Unix-friendly design.

Reading formatted data

fscanf(file, format, ...) is scanf for any file, and fprintf(file, format, ...) is printf for any file. fprintf(stderr, ...) is the standard way to print error messages: they go to a separate stream, so they are not mixed into output that is piped to another program.

Key takeaways

  • fopen gives a FILE * or NULL - always check. fclose everything you open.

  • "r" reads, "w" creates or erases, "a" appends.

  • Read lines with fgets until it returns NULL. Functions taking a FILE * work equally well with stdin.

Lesson quiz

5 questions · pass with 4 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write real C

These run for real. Write the program, press Run tests, and read what the compiler tells you - learning to read compiler messages is half of learning C.

Exercise 1

wc, the tiny version

+25 XP

Write void count(FILE *input, int *lines, int *words, int *chars) that counts lines, words and characters, like the Unix wc tool. A word is a run of non-whitespace characters. main calls it with stdin and prints the three counts separated by spaces.

For the input the quick fox followed by a newline, the output is 1 3 14.

  • One line
  • Extra spaces
main.c
Loading editor…

Your code is compiled with gcc 14 (-Wall -Wextra) and run on Compiler Explorer (godbolt.org), a free public service.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Sign in to ask questions, help other learners, and earn XP for taking part.

Loading posts…

Gostou da aula? 😆👍
Apoie nosso trabalho com uma doação: