$ overview
overview/0x0D·Working With The System

File I/O

Reading and writing files on disk with FILE pointers.

File access in C goes through a FILE *, a pointer to a structure the standard library uses to track an open file's position and buffering. The functions that operate on it mirror printf and scanf closely, since stdin and stdout are themselves just pre-opened FILE * streams.

Opening and closing a file

open.c
1#include <stdio.h>
2 
3FILE *file = fopen("data.txt", "r");
4 
5if (file == NULL) {
6 printf("Could not open file.\n");
7 return 1;
8}
9 
10// ... work with the file ...
11 
12fclose(file);

The second argument to fopen is the mode: "r" for reading, "w" for writing (creates the file, or erases it if it already exists), "a" for appending. fopen returns NULL on failure — a missing file, no permission, and so on — and that always has to be checked before use.

Writing to a file

write.c
1FILE *file = fopen("output.txt", "w");
2if (file == NULL) return 1;
3 
4fprintf(file, "Score: %d\n", 95);
5fprintf(file, "Name: %s\n", "Nour");
6 
7fclose(file);

fprintf works exactly like printf, but takes the target stream as its first argument.

Reading a file line by line

read.c
1FILE *file = fopen("data.txt", "r");
2if (file == NULL) return 1;
3 
4char line[256];
5while (fgets(line, sizeof(line), file) != NULL) {
6 printf("%s", line);
7}
8 
9fclose(file);

fgets returns NULL once it reaches the end of the file, which is what naturally ends the loop above — no separate "end of file" check needed.

warning: Always close what you open
A FILE * you forget to fclose may leave buffered writes never actually reaching disk, and ties up a limited operating-system resource until the program exits. Every fopen should have a matching fclose, the same discipline as malloc and free.

Reading structured data

fscanf reads formatted data from a file the same way scanf reads from the keyboard:

fscanf.c
1int id;
2float score;
3fscanf(file, "%d %f", &id, &score);