Introduction
Software applications frequently require permanent data storage beyond program execution. Unlike variables stored in RAM, which lose their contents when a program terminates, files provide persistent storage on disks such as HDDs or SSDs. This capability enables applications to save user preferences, store transaction records, or maintain configuration data across sessions.
In the C programming language, file handling involves a structured approach to data persistence. This article explains the fundamental concepts of file handling, including file types, operation modes, and practical implementation techniques. You will gain an understanding of how to create, read, write, and close files using standard library functions. Additionally, the distinction between text files and binary files will be clarified with concrete examples and performance considerations.
(toc) #title=(Table of Content)
What Is a File in Programming?
A file represents a collection of related information stored on a persistent storage medium. Consider a digital invoice: it contains customer details, item quantities, prices, and the total amount. Each piece of data constitutes a record, and the complete set forms the file. Files organize data hierarchically—directories contain files, and files contain records or bytes.
From a systems perspective, a file is a stream of bytes with an associated metadata structure containing creation timestamps, access permissions, and size information. When a C program interacts with a file, the operating system returns a file descriptor or stream pointer that the program uses for subsequent read and write operations.
To declare a file pointer in C, use the following syntax:
FILE *filePointer;
FILE is a structure defined in stdio.h, and the asterisk denotes a pointer variable that stores the memory address of the file stream.
Text Files vs Binary Files
Files in C fall into two primary classifications: text files and binary files. Each type serves distinct use cases with different storage efficiencies and error tolerance characteristics.
Text Files
Text files contain human-readable characters including alphabets (A-Z, a-z), numeric digits (0-9), and special symbols (such as @, #, $, %). Every character in a text file occupies exactly one byte of memory using ASCII or Unicode encoding.
Example: The number sequence "5, 8, 12, 3" stored as a text file contains four distinct characters. Each digit occupies one byte, resulting in total storage of four bytes.
| Data Stored | Text File Storage | Bytes Used |
|---|---|---|
| "8, 15, 22" | Each digit as separate character | 7 bytes (including commas) |
| "105" | Digits '1','0','5' | 3 bytes |
Errors in text files, such as a misspelled word, can be corrected easily using any standard text editor. Text files are portable across different operating systems with minimal compatibility issues.
Binary Files
Binary files store data in the same format as computer memory representation—sequences of zeros and ones. The integer value 270, for example, occupies two or four bytes depending on system architecture, unlike its text representation which would require three separate character bytes ('2','7','0').
A binary file containing the integer sequence 5, 12, 8 stores these numbers as fixed-size binary values. On a typical 32-bit system using two-byte integers, this occupies exactly six bytes of storage—substantially less than the equivalent text representation.
Storage Comparison: The value 945 stored as text uses three bytes ('9','4','5'). The same value stored as a binary integer (assuming two-byte representation) uses two bytes, representing a 33% reduction in storage requirements.
However, binary files require compatible software to interpret their contents. A movie file (.mp4) needs a media player such as VLC. Similarly, a custom binary data file requires specialized parsing logic. Error correction in binary files proves more challenging because byte-level corruption may misinterpret entire data structures.
Sequential Access vs Random Access Files
Files are further categorized by their access methodology:
Sequential Files store data in a linear arrangement where records follow one another in order. Student roll numbers (1, 2, 3, 4...) exemplify this pattern. To reach record 25, the program must read records 1 through 24 sequentially.
Random Access Files allow direct retrieval of any record without traversing preceding data. Database systems frequently employ random access where a customer record with ID 348 can be accessed directly using its byte offset within the file.
Five Core File Operations
File handling in C encompasses five essential operations:
- Creating a new file — Establishing a file on disk with a specified name and initial empty state
- Opening an existing file — Establishing a stream connection to a file already present on disk
- Reading a file — Transferring data from the file into program memory variables
- Writing to a file — Transferring data from program memory into the file
- Closing a file — Flushing buffers and releasing the file stream resource
File Opening Modes Explained
The fopen() function accepts a mode parameter that determines permitted operations on the file.
Text File Modes
| Mode | Operation | Description |
|---|---|---|
"r" |
Read only | Opens existing file for reading. Fails if file does not exist. |
"r+" |
Read and write | Opens existing file for both operations. |
"w" |
Write | Creates new file or truncates existing content. Previous data lost. |
"w+" |
Write and read | Creates or truncates file, permits both operations. |
"a" |
Append | Opens or creates file; all writes add data at end. |
"a+" |
Append and read | Opens file for reading and appending. |
Critical distinction: Write mode ("w") destroys previous file content. Append mode ("a") preserves existing data and adds new information at the end. For example, a log file containing "User logged in at 08:00" updated with append mode will retain that line while adding "User logged out at 17:00" below it.
Binary File Modes
Binary modes use the same letters with a 'b' suffix: "rb", "rb+", "wb", "wb+", "ab", "ab+". These operate identically to text modes but disable newline translation, preserving raw byte values.
Practical Implementation: Creating and Writing to a File
The following C program demonstrates file creation, text writing, and proper closure:
#include <stdio.h>
void main() {
FILE *filePtr;
// Create or open file in write mode
filePtr = fopen("D:\\data\\output.txt", "w");
// Write content to the file
fprintf(filePtr, "Transaction record: Invoice #4821\n");
fprintf(filePtr, "Customer: Acme Corporation\n");
fprintf(filePtr, "Total amount: $1,247.50");
// Close the file
fclose(filePtr);
}
When executed, this program performs three actions:
- Creates
output.txtin the specified directory (parent directory must exist) - Writes three lines of text into the file
- Releases the file pointer resource
No console output appears upon successful execution. Verify file creation by navigating to the specified directory and opening the file with any text editor.
Reading Data from an Existing File
To retrieve and display file contents, use fscanf() or fgets():
#include <stdio.h>
void main() {
FILE *filePtr;
char buffer[200];
filePtr = fopen("D:\\data\\output.txt", "r");
if (filePtr == NULL) {
printf("File could not be opened.\n");
return;
}
while (fscanf(filePtr, "%s", buffer) != EOF) {
printf("%s ", buffer);
}
fclose(filePtr);
}
Explanation: The program declares a character array buffer of 200 bytes. The while loop calls fscanf() repeatedly, transferring data from the file to the buffer until the End-Of-File marker is reached. Each extracted word prints to the console. The condition != EOF ensures the loop terminates precisely when all data has been read.
Comparison of Writing Functions
| Function | Purpose | Data Type | Example |
|---|---|---|---|
fprintf() |
Formatted output | Variables, strings, numbers | fprintf(fp, "Value: %d", 42); |
fputs() |
String output | String only | fputs("Hello", fp); |
putc() |
Character output | Single character | putc('A', fp); |
Conclusion
File handling forms the backbone of persistent data storage in C applications. Understanding the distinction between text and binary files enables developers to choose appropriate storage strategies based on human readability requirements versus storage efficiency demands. Text files offer portability and ease of debugging, while binary files provide compact storage and faster I/O operations.
Modern applications increasingly combine both approaches—using text files for configuration and logs while employing binary formats for performance-critical data storage. By mastering the five file operations (create, open, read, write, close) and selecting appropriate modes, developers can build robust data management systems that preserve information across program executions.