🔴 Advanced  ·  Lesson 37

File Read & Write

Four ways to read and write

Once a file is open (see file handling basics for fopen/fclose), C gives you four ways to move data in and out. Each suits a different shape of data:

LevelWrite / ReadBest for
Characterfputc / fgetcOne char at a time
Linefputs / fgetsText lines
Formattedfprintf / fscanfMixed values / records
Binaryfwrite / freadStructs, arrays, raw data

Character I/O: fgetc and fputc

fputc writes one character; fgetc reads one, returning EOF at the end of the file.

C Language
FILE *fp = fopen("data.txt", "w");
fputc('H', fp); fputc('i', fp);      // write two chars
fclose(fp);

fp = fopen("data.txt", "r");
int ch;
while ((ch = fgetc(fp)) != EOF)      // read till end
    putchar(ch);
fclose(fp);
Output:
Hi

Line I/O: fgets and fputs

fputs writes a string; fgets reads a line safely into a fixed buffer.

C Language
FILE *fp = fopen("note.txt", "w");
fputs("Hello file\n", fp);
fputs("Second line\n", fp);
fclose(fp);

fp = fopen("note.txt", "r");
char line[100];
while (fgets(line, sizeof(line), fp) != NULL)
    printf("%s", line);
fclose(fp);
Output:
Hello file
Second line
💡 fgets is safe

fgets takes the buffer size, so it never writes past your array. Prefer it over the old unsafe gets.

Formatted I/O: fscanf and fprintf

For records with mixed types (name, age, marks), fprintf and fscanf work like printf/scanf but on a file.

C Language
FILE *fp = fopen("rec.txt", "w");
fprintf(fp, "%s %d\n", "Aman", 95);   // write a record
fclose(fp);

fp = fopen("rec.txt", "r");
char name[20]; int marks;
fscanf(fp, "%s %d", name, &marks);    // read it back
printf("%s scored %d\n", name, marks);
fclose(fp);
Output:
Aman scored 95

Binary I/O: fread and fwrite

To store a whole structure exactly as it sits in memory, use binary mode with fwrite and fread.

C Language
struct Student { char name[20]; int marks; };
struct Student s = {"Ravi", 88};

FILE *fp = fopen("s.dat", "wb");      // wb = write binary
fwrite(&s, sizeof(s), 1, fp);
fclose(fp);

struct Student r;
fp = fopen("s.dat", "rb");            // rb = read binary
fread(&r, sizeof(r), 1, fp);
printf("%s %d\n", r.name, r.marks);
fclose(fp);
Output:
Ravi 88

Which method should you use?

  • Character — copying files, counting characters, simple filters.
  • Line — reading text files line by line (logs, config).
  • Formatted — human-readable records with mixed fields.
  • Binary — saving structs/arrays fast and compact, not for humans to read.

Common mistakes

  • Comparing fgetc to a char instead of intEOF needs int.
  • Using text mode for binary data or the reverse.
  • Reading with a different struct layout than you wrote (binary files are not portable across layouts).
  • Forgetting to check the return value of read/write for errors.
🏋️ Practice

Write three student records with fprintf, then read them all back in a loop with fscanf until it stops returning matches. Then try the same with fwrite/fread and compare the file sizes.

Summary

  • C has four I/O levels: character, line, formatted and binary.
  • fgetc/fputc handle single characters; loop until EOF.
  • fgets/fputs handle lines safely.
  • fprintf/fscanf handle readable records; fwrite/fread handle raw binary.
  • Choose the level that matches your data and whether it must be human-readable.

Frequently Asked Questions

What are the different ways to read and write files in C?
C offers four levels: character by character with fgetc/fputc, line by line with fgets/fputs, formatted values with fscanf/fprintf, and raw binary blocks with fread/fwrite. You pick the one that matches the shape of your data.
What is the difference between fprintf and fwrite?
fprintf writes human-readable text — numbers become characters like "42" — so the file can be opened in any editor. fwrite writes the raw bytes of the data exactly as they sit in memory, which is compact and fast but not readable as text. Use fprintf for text files and fwrite for binary files.
What does fgets do in C?
fgets reads one line from a file into a character array, stopping at a newline or when the buffer is full, and it keeps the newline character. It is safer than older functions because you tell it the maximum size, so it will not overflow your buffer.
When should I use fread and fwrite instead of fprintf?
Use fread/fwrite when you want to store data such as whole structures or arrays exactly as they are in memory — it is faster and smaller than text. Use fprintf/fscanf when you need the file to be human-readable or shared with other programs.
How do you read a whole file character by character in C?
You call fgetc in a loop and stop when it returns the special value EOF, which marks the end of the file. Each call returns the next character, so the loop walks through the entire file one character at a time.
← Back to C Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।