File Handling

Write data to files and read it back with fopen, fprintf and fgets.

To keep data after a program ends, write it to a file. C uses the FILE type from stdio.h, together with a handful of functions that mirror the ones you already know: fprintf is printf for files, and fscanf is scanf for files.

Writing a file

fopen(name, mode) opens a file and returns a FILE *, or NULL on failure. Mode "w" creates the file or empties an existing one.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("scores.txt", "w");
    if (fp == NULL) {
        printf("Could not open file\n");
        return 1;
    }
    fprintf(fp, "Asha 88\n");
    fprintf(fp, "Ravi 72\n");
    fprintf(fp, "Meera 95\n");
    fclose(fp);
    printf("File written.\n");
    return 0;
}
Output
File written.

Reading line by line

fgets(buffer, size, fp) reads one line, up to size - 1 characters, and returns NULL at the end of the file.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("notes.txt", "w");
    if (fp == NULL) return 1;
    fputs("first line\nsecond line\n", fp);
    fclose(fp);

    char line[100];
    int n = 0;
    fp = fopen("notes.txt", "r");
    if (fp == NULL) return 1;
    while (fgets(line, sizeof(line), fp) != NULL) {
        n++;
        printf("%d: %s", n, line);
    }
    fclose(fp);
    return 0;
}
Output
1: first line
2: second line

fgets keeps the newline at the end of each line, so the printf above does not add another one.

Reading formatted data

fscanf reads values in the same way as scanf, and returns how many it matched. That makes it easy to loop until the data runs out.

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("scores.txt", "w");
    if (fp == NULL) return 1;
    fprintf(fp, "Asha 88\nRavi 72\nMeera 95\n");
    fclose(fp);

    fp = fopen("scores.txt", "r");
    if (fp == NULL) return 1;
    char name[30];
    int score, total = 0, count = 0;
    while (fscanf(fp, "%29s %d", name, &score) == 2) {
        total += score;
        count++;
    }
    fclose(fp);
    printf("%d students, average %.1f\n", count, (double)total / count);
    return 0;
}
Output
3 students, average 85.0

File modes

  • "r": read. The file must exist.
  • "w": write. Creates the file, or erases it if it exists.
  • "a": append. Adds to the end, creating the file if needed.
  • Add b (for example "rb") to work with binary files.

GATE-style practice questions

GATE-styleMCQ · one correct answer

What does the following program print?

#include <stdio.h>
int main(void) {
    FILE *f = fopen("t.txt", "w");
    fprintf(f, "%d %d %d", 4, 8, 15);
    fclose(f);
    f = fopen("t.txt", "r");
    int x, total = 0, n = 0;
    while (fscanf(f, "%d", &x) == 1) { total += x; n++; }
    fclose(f);
    printf("%d %d\n", n, total);
    return 0;
}
Show answer and explanationAnswer: B

The file contains "4 8 15". fscanf reads one number per call and returns 1 each time, then returns EOF at the end, so 3 numbers are read with a total of 27.

GATE-styleMSQ · one or more correct answers

A file is opened with fopen("log.txt", "a"). Which statements are true? (Select all that apply.)

Show answer and explanationAnswer: A, B

Mode "a" (append) creates the file if needed and always writes at the end, keeping what is already there. Mode "w" is the one that erases existing contents.