Files on disk Ready
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

Open, use, close

Working with a file always follows the same three steps. fopen(name, mode) opens it and returns a FILE * — a pointer to a structure that remembers the file and the current position — or NULL when it fails. Then you read or write with functions that look like the console ones with an f in front (fprintf, fscanf, fgets, fputs, fgetc, fputc). Finally fclose writes out anything still waiting and releases the file.

FILE *fp = fopen("data.txt", "w");   // 1. open
if (fp == NULL) {                      //    always check!
    perror("data.txt");
    return 1;
}
fprintf(fp, "%d\n", 42);               // 2. use
fclose(fp);                            // 3. close
fopen modes for text files
Mode Meaning File must exist? Old content
"r" read yes — else NULL kept
"w" write no — it is created ERASED
"a" append (write at the end) no — it is created kept
"r+" read and write yes kept
"w+" read and write no erased
"a+" read, and write at the end no kept

Opening and closing

  1. FILE *fp = fopen("name.txt", "r"); — FILE is declared in stdio.h.
  2. fopen returns NULL if the file is missing ("r"), the folder is wrong or access is denied.
  3. perror("name.txt") prints why, e.g. "name.txt: No such file or directory".
  4. fclose(fp) flushes the data to disk and frees the FILE.
  5. A program can only have a limited number of files open — close them when done.

Writing text

  1. fprintf(fp, format, …) — printf into a file.
  2. fputs("text", fp) writes a string (no newline added).
  3. fputc('A', fp) writes one character.
  4. "w" starts with an empty file; "a" adds to the end.
  5. Writes are buffered: they reach the disk at fclose (or fflush).

Reading text and EOF

  1. fscanf(fp, "%d", &n) returns how many values it read — or EOF at the end.
  2. fgets(line, sizeof line, fp) reads one line (with '\n') or returns NULL at the end.
  3. fgetc(fp) returns the next character as an int, or EOF (−1).
  4. Loop on the read function's result: while (fgets(…) != NULL).
  5. Each read moves the file position forward; it starts at 0 for "r".
Walkthrough

A small diary: append a line, then read them all

Every line, explained.

1 #include <stdio.h>
2
3 int main(void)
4 {
5 FILE *fp = fopen("diary.txt", "a"); Creates the file the first time, adds to it afterwards.
6 if (fp == NULL) {
7 perror("diary.txt"); Prints the reason the file could not be opened.
8 return 1;
9 }
10 fprintf(fp, "Learned files in C\n");
11 fclose(fp);
12
13 fp = fopen("diary.txt", "r"); Open again, now for reading, at position 0.
14 if (fp == NULL) return 1;
15 char line[100];
16 int n = 0;
17 while (fgets(line, sizeof line, fp) != NULL) One line per round, until NULL.
18 printf("%d: %s", ++n, line); line already ends with '\n'.
19 fclose(fp);
20 printf("%d entries\n", n); Grows by one every time you run the program.
21 return 0;
22 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

Not checking fopen

✗ Wrong
FILE *fp = fopen("data.txt", "r");
fscanf(fp, "%d", &n);   // crash if fp is NULL
✓ Right
FILE *fp = fopen("data.txt", "r");
if (fp == NULL) { perror("data.txt"); return 1; }

Missing files are normal. Using a NULL FILE * crashes the program.

Using "w" when you meant "a"

✗ Wrong
fopen("log.txt", "w");   // old log erased
✓ Right
fopen("log.txt", "a");   // add to the end

"w" empties the file the moment it is opened.

while (!feof(fp))

✗ Wrong
while (!feof(fp)) {
    fscanf(fp, "%d", &n);   // last value counted twice
    sum += n;
}
✓ Right
while (fscanf(fp, "%d", &n) == 1)
    sum += n;

feof only becomes true AFTER a read has failed. Test the read itself.

Storing fgetc in a char

✗ Wrong
char c;
while ((c = fgetc(fp)) != EOF)
✓ Right
int c;
while ((c = fgetc(fp)) != EOF)

EOF is −1, an int. In a char it can be confused with a real character or never match.

Forgetting fclose

✗ Wrong
fprintf(fp, "%d", total);
return 0;   // data may never reach the disk
✓ Right
fprintf(fp, "%d", total);
fclose(fp);
return 0;

Writes are buffered. Close (or fflush) to be sure they are saved.

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

What does fopen return when the file cannot be opened?

Question 2

A file holds "old". It is opened with "w" and "new" is written. What does it hold?

Question 3

The same file holding "old" is opened with "a" and "new" is written. What does it hold?

Question 4

What does fgets return at the end of the file?

Question 5

Why should the variable that receives fgetc be an int?

Assessment

File Handling Basics quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.