File Handling in C
All the programs discussed so far work with data that is stored in RAM (memory) — which is temporary. When the program ends, all data is lost. File handling allows a C program to permanently store data by reading from and writing to files on the disk.
Files are useful for saving records, logs, configuration data, and processing large datasets that cannot fit in memory.
Types of Files in C
- Text Files: Store data as plain text (human-readable). Each line ends with a newline character. Extension:
.txt,.csv, etc. - Binary Files: Store data in binary format (not human-readable). More compact and faster. Extension:
.bin,.dat, etc.
File Handling Steps
- Open the file using
fopen() - Read or Write using file I/O functions
- Close the file using
fclose()
The FILE Pointer
A FILE pointer is a special type defined in <stdio.h> that holds all the information about an open file — its current position, mode, buffer, etc.
FILE *fp; // declare a file pointer
Opening a File — fopen()
Syntax
FILE *fopen(const char *filename, const char *mode);
fopen() returns a FILE pointer if successful, or NULL if the file could not be opened.
File Opening Modes
| Mode | Meaning | File Exists | File Not Exists |
|---|---|---|---|
| "r" | Read only | Opens for reading | Returns NULL (error) |
| "w" | Write only | Overwrites existing data | Creates new file |
| "a" | Append | Adds to end of file | Creates new file |
| "r+" | Read and Write | Opens for both | Returns NULL (error) |
| "w+" | Read and Write | Overwrites file | Creates new file |
| "a+" | Read and Append | Reads and appends | Creates new file |
| "rb","wb","ab" | Binary modes | Same as above but binary format | — |
Closing a File — fclose()
Always close a file after use to save data and free system resources.
fclose(fp);
Writing to a Text File — fprintf() and fputs()
Using fprintf()
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("students.txt", "w"); // open in write mode
if (fp == NULL)
{
printf("Error opening file!\n");
return 1;
}
fprintf(fp, "Alice,20,8.75\n");
fprintf(fp, "Bob,21,7.90\n");
fprintf(fp, "Carol,22,9.20\n");
fclose(fp);
printf("Data written to students.txt\n");
return 0;
}
Using fputs()
#include <stdio.h>
int main()
{
FILE *fp = fopen("notes.txt", "w");
if (fp != NULL)
{
fputs("Line 1: Welcome to C programming.\n", fp);
fputs("Line 2: File handling is easy.\n", fp);
fclose(fp);
printf("File written.\n");
}
return 0;
}
Reading from a Text File — fscanf() and fgets()
Using fscanf()
#include <stdio.h>
int main()
{
FILE *fp;
char name[50];
int age;
float gpa;
fp = fopen("students.txt", "r"); // open in read mode
if (fp == NULL)
{
printf("Cannot open file!\n");
return 1;
}
printf("Name Age GPA\n");
while (fscanf(fp, "%[^,],%d,%f\n", name, &age, &gpa) == 3)
{
printf("%-10s %-4d %.2f\n", name, age, gpa);
}
fclose(fp);
return 0;
}
Using fgets()
#include <stdio.h>
int main()
{
FILE *fp;
char line[200];
fp = fopen("notes.txt", "r");
if (fp == NULL)
{
printf("Cannot open file!\n");
return 1;
}
while (fgets(line, sizeof(line), fp) != NULL)
{
printf("%s", line); // print each line
}
fclose(fp);
return 0;
}
Appending to a File
Using "a" mode adds new content at the end of the file without erasing existing content.
#include <stdio.h>
int main()
{
FILE *fp = fopen("students.txt", "a"); // append mode
if (fp != NULL)
{
fprintf(fp, "David,23,8.10\n");
fclose(fp);
printf("New record appended.\n");
}
return 0;
}
Reading and Writing Characters — fgetc() and fputc()
#include <stdio.h>
int main()
{
FILE *fp;
char ch;
// Write characters to file
fp = fopen("chars.txt", "w");
for (ch = 'A'; ch <= 'E'; ch++)
fputc(ch, fp);
fclose(fp);
// Read characters from file
fp = fopen("chars.txt", "r");
printf("File content: ");
while ((ch = fgetc(fp)) != EOF) // EOF = End of File
printf("%c", ch);
printf("\n");
fclose(fp);
return 0;
}
Output
File content: ABCDE
Binary File Operations — fread() and fwrite()
Binary files store data in raw binary format, which is faster and more compact than text files for storing structured data.
#include <stdio.h>
struct Student
{
char name[50];
int age;
float gpa;
};
int main()
{
FILE *fp;
struct Student s1 = {"Alice", 20, 8.75};
struct Student s2;
// Write structure to binary file
fp = fopen("student.bin", "wb");
fwrite(&s1, sizeof(s1), 1, fp);
fclose(fp);
// Read structure from binary file
fp = fopen("student.bin", "rb");
fread(&s2, sizeof(s2), 1, fp);
fclose(fp);
printf("Name : %s\n", s2.name);
printf("Age : %d\n", s2.age);
printf("GPA : %.2f\n", s2.gpa);
return 0;
}
Output
Name : Alice
Age : 20
GPA : 8.75
File Position Functions
| Function | Description |
|---|---|
| ftell(fp) | Returns the current position in the file |
| fseek(fp, offset, origin) | Moves the file pointer to a specific position |
| rewind(fp) | Moves the file pointer back to the beginning |
| feof(fp) | Returns non-zero if end of file is reached |
| ferror(fp) | Returns non-zero if a file error occurred |
fseek() Origin Values
| Constant | Value | Meaning |
|---|---|---|
| SEEK_SET | 0 | From beginning of file |
| SEEK_CUR | 1 | From current position |
| SEEK_END | 2 | From end of file |
Error Handling in File Operations
Always check if a file was opened successfully before performing operations:
FILE *fp = fopen("data.txt", "r");
if (fp == NULL)
{
perror("Error"); // prints system error message
return 1;
}
Summary of File I/O Functions
| Function | Purpose |
|---|---|
| fopen() | Open a file |
| fclose() | Close a file |
| fprintf() | Write formatted text to file |
| fscanf() | Read formatted data from file |
| fputs() | Write a string to file |
| fgets() | Read a line from file |
| fputc() | Write a single character to file |
| fgetc() | Read a single character from file |
| fwrite() | Write binary data to file |
| fread() | Read binary data from file |
| fseek() | Move file pointer to a position |
| rewind() | Reset file pointer to start |
Summary
File handling in C enables programs to persist data beyond their lifetime. Files can be opened, read, written, and appended using the FILE pointer and standard functions from <stdio.h>. Text files store human-readable content, while binary files are compact and fast. Always check if a file opened successfully, always close files after use, and always handle EOF properly to write robust, error-free file-handling code.
