thecodex.expert · The Codex Family of Knowledge
C

File IO

fopen returns NULL on failure, not an exception — and forgetting to check that, or forgetting fclose entirely, are both real, common C bugs.

C17 / C23 Always check fopen for NULL Last verified:
Canonical Definition

fopen(path, mode) opens a file and returns a FILE pointer (or NULL on failure) — mode strings like "r", "w", "a" control read/write/append behavior and whether the file is treated as text or binary. Line-oriented functions like fgets/fputs handle text a line at a time; fread/fwrite handle raw binary data in fixed-size blocks. Every successfully opened file must eventually be closed with fclose, which flushes any buffered output to disk — skipping it risks losing buffered writes that were never actually flushed, not just a resource leak.

Reading a text file line by line

fgets reads up to one line (or buffer-size bytes, whichever comes first) and returns NULL once it hits end-of-file — checking that return value is what correctly ends the loop.

Cread_lines.c
FILE *f = fopen("data.txt", "r");
if (f == NULL) {
    perror("fopen failed");
    return 1;
}

char line[256];
while (fgets(line, sizeof(line), f) != NULL) {
    printf("%s", line);
}

fclose(f);   // required — flushes and releases the file handle

Writing to a file

"w" mode truncates an existing file to zero length before writing (destroying its previous contents); "a" mode appends to the end instead — confusing the two is a real, easy way to accidentally lose data.

Cwrite_file.c
FILE *f = fopen("output.txt", "w");   // "w" TRUNCATES any existing content
if (f == NULL) {
    perror("fopen failed");
    return 1;
}

fprintf(f, "Line %d\n", 1);
fputs("Another line\n", f);

fclose(f);

Binary I/O: fread and fwrite

fread's return value is the number of complete elements actually read, which can be less than requested at end-of-file or on error — always check it rather than assuming the full request succeeded.

Cbinary_io.c
int numbers[5] = {1, 2, 3, 4, 5};

FILE *f = fopen("data.bin", "wb");   // "b" for binary mode
fwrite(numbers, sizeof(int), 5, f);
fclose(f);

int loaded[5];
f = fopen("data.bin", "rb");
size_t count = fread(loaded, sizeof(int), 5, f);   // check count against the expected 5
fclose(f);

Sources

1
ISO/IEC 9899 (C Standard), "File input/output," cppreference.com/w/c/io.