Reading — step 1 of 7
Learn
K&R Chapter 7 covers the standard I/O library — fopen, fread, fwrite, fgets, fprintf, fclose. Reading and writing files is fundamental.
Opening and closing
#include <stdio.h>
FILE* fp = fopen("data.txt", "r");
if (fp == NULL) {
perror("fopen failed");
return 1;
}
/* ... use fp ... */
fclose(fp);
Always check the return value of fopen — it returns NULL on failure (file doesn't exist, permission denied, out of file descriptors). Use perror to print a system-derived error message.
Always close with fclose. Otherwise you leak file descriptors and may lose buffered writes.
File modes
The second arg to fopen is the mode string:
"r"— read; file must exist"w"— write; TRUNCATES existing file or creates new"a"— append; creates if missing"r+"— read+write; file must exist"w+"— read+write; truncates"a+"— append+read
Add b for binary mode: "rb", "wb". On Unix this is the same as text mode, but on Windows binary mode is REQUIRED to avoid \r\n translation when reading binary files.
Reading a line at a time
char line[1024];
FILE* fp = fopen("input.txt", "r");
if (fp != NULL) {
while (fgets(line, sizeof(line), fp) != NULL) {
printf("got: %s", line); // line includes trailing \n if present
}
fclose(fp);
}
fgets(buf, n, fp) reads up to n-1 chars OR until newline OR until EOF, then null-terminates. Returns NULL at EOF (or error).
Reading and writing binary
/* Write 10 ints to a binary file */
int nums[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
FILE* fp = fopen("data.bin", "wb");
fwrite(nums, sizeof(int), 10, fp);
fclose(fp);
/* Read them back */
int loaded[10];
fp = fopen("data.bin", "rb");
size_t got = fread(loaded, sizeof(int), 10, fp);
fclose(fp);
fread(buf, size, count, fp) and fwrite(buf, size, count, fp) transfer count * size bytes. They return the number of ELEMENTS successfully transferred (which may be less than count on error / partial read).
Formatted I/O on files
Like printf/scanf but on a FILE*:
FILE* fp = fopen("out.txt", "w");
fprintf(fp, "name=%s age=%d\n", name, age);
fclose(fp);
fprintf is the file version of printf. fscanf is the file version of scanf.
stdin, stdout, stderr
The three standard streams are pre-opened FILE* values:
fprintf(stderr, "warning: %s\n", msg); // write to stderr
These are the same as the unnamed streams that printf/scanf use by default.
Common mistakes
- Not checking fopen's return value — using a NULL FILE* is undefined behavior.
- Forgetting fclose — leaks file descriptors AND loses buffered output (writes can vanish without explicit flush).
- Mode mistakes —
"w"truncates the file. Use"a"to add to an existing file. - Forgetting binary mode on Windows —
\r\ntranslation corrupts non-text data. - Buffer overflow with fgets — the second arg must be the buffer's actual size (not its length-of-content).
- Not stripping the trailing \n from fgets output — common when comparing strings read from a file.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…