Bytebook Compiler

Structures, Files & More

File Handling

Save data that outlives your program: open, write, read, append and close text files with fopen, fprintf, fscanf, fgets and friends.

4 min read4 runnable examples4-question quiz

Variables vanish when a program ends. Files keep data on disk. C works with files through a FILE * pointer from stdio.h.

The pattern is always the same: open → read or write → close.

Opening a file

C
FILE *fp = fopen("marks.txt", "w");
if (fp == NULL) { perror("fopen"); return 1; }   // always check!
Mode Meaning If the file exists If it does not
"r" read read from the start fails (returns NULL)
"w" write erases it creates it
"a" append adds at the end creates it
"r+" read and write opens it fails
"w+" read and write erases it creates it
"a+" read and append opens it creates it

Add b for binary files: "rb", "wb".

Writing and reading text

C
#include <stdio.h>

int main(void) {
    FILE *fp = fopen("marks.txt", "w");
    if (!fp) { perror("marks.txt"); return 1; }
    fprintf(fp, "%s %d\n", "Asha", 91);
    fprintf(fp, "%s %d\n", "Ravi", 78);
    fprintf(fp, "%s %d\n", "Meera", 85);
    fclose(fp);
    printf("Saved 3 records.\n");

    fp = fopen("marks.txt", "r");
    if (!fp) { perror("marks.txt"); return 1; }
    char name[20];
    int marks, total = 0, count = 0;
    while (fscanf(fp, "%19s %d", name, &marks) == 2) {   // stop when a read fails
        printf("%-6s %d\n", name, marks);
        total += marks;
        count++;
    }
    fclose(fp);
    printf("Class average: %.2f\n", (double)total / count);
    return 0;
}
Output
Saved 3 records.
Asha   91
Ravi   78
Meera  85
Class average: 84.67

Line by line with fgets, and appending

C
#include <stdio.h>
#include <string.h>

int main(void) {
    FILE *fp = fopen("diary.txt", "w");
    fputs("Monday: started C file handling\n", fp);
    fclose(fp);

    fp = fopen("diary.txt", "a");                 // append keeps the old content
    fputs("Tuesday: wrote my first log file\n", fp);
    fclose(fp);

    char line[100];
    int n = 0;
    fp = fopen("diary.txt", "r");
    while (fgets(line, sizeof line, fp) != NULL) {
        line[strcspn(line, "\n")] = '\0';
        printf("%d | %s\n", ++n, line);
    }
    fclose(fp);
    return 0;
}
Output
1 | Monday: started C file handling
2 | Tuesday: wrote my first log file

Character by character: copy a file and count stats

C
#include <stdio.h>

int main(void) {
    FILE *out = fopen("source.txt", "w");
    fputs("Files are just bytes.\nRead them one char at a time!\n", out);
    fclose(out);

    FILE *in = fopen("source.txt", "r");
    FILE *copy = fopen("copy.txt", "w");
    int ch, chars = 0, lines = 0, words = 0, inWord = 0;
    while ((ch = fgetc(in)) != EOF) {          // ch must be int to hold EOF
        fputc(ch, copy);
        chars++;
        if (ch == '\n') lines++;
        if (ch == ' ' || ch == '\n' || ch == '\t') inWord = 0;
        else if (!inWord) { inWord = 1; words++; }
    }
    fclose(in);
    fclose(copy);
    printf("chars %d, words %d, lines %d\n", chars, words, lines);
    return 0;
}
Output
chars 52, words 11, lines 2

Binary files: saving structures

fwrite and fread copy raw bytes, which makes saving whole structures easy and fast:

C
#include <stdio.h>

typedef struct { int id; char item[16]; double price; } Product;

int main(void) {
    Product stock[3] = {{1, "Notebook", 45.0}, {2, "Pen", 10.5}, {3, "Calculator", 799.0}};
    FILE *fp = fopen("stock.dat", "wb");
    fwrite(stock, sizeof(Product), 3, fp);
    fclose(fp);

    Product p;
    fp = fopen("stock.dat", "rb");
    fseek(fp, 2 * sizeof(Product), SEEK_SET);     // jump straight to record #3
    fread(&p, sizeof(Product), 1, fp);
    printf("Record 3: %s costs Rs %.2f\n", p.item, p.price);
    rewind(fp);                                   // back to the start
    fread(&p, sizeof(Product), 1, fp);
    printf("Record 1: %s\n", p.item);
    fclose(fp);
    return 0;
}
Output
Record 3: Calculator costs Rs 799.00
Record 1: Notebook
Function Purpose
fopen, fclose open and close
fprintf, fscanf formatted write / read
fputs, fgets write / read a line
fputc, fgetc write / read one character
fwrite, fread write / read raw blocks (binary)
fseek, ftell, rewind move around in a file
feof, ferror check for end of file or an error

Test yourself

4 questions · pick an answer to check it instantly

  1. 1

    Which mode opens a file for writing without erasing its current contents?

  2. 2

    What does fopen return if the file cannot be opened?

  3. 3

    Why should the variable receiving fgetc(fp) be an int?

  4. 4

    Which function moves the file position to a specific byte offset?