File handling is one of the most essential features in C++. It allows programs to store data permanently on a disk rather than keeping it only in memory during execution. Files provide a way to read, write, and manipulate data efficiently. Without file handling, the data entered by a user would be lost once the program stops running.
C++ offers powerful tools for managing files through the fstream library. Using this library, you can easily perform operations like creating, opening, writing, reading, appending, and closing files.
In this post, we will explore everything about file handling in C++ in detail — from the basics of file streams to advanced file operations and error handling.
What Is File Handling?
When you write a program, data is stored temporarily in the computer’s RAM. Once the program ends, all the data is lost. To keep the data permanently, you need to store it in a file.
File handling is the process of creating, reading, writing, and updating files using programming languages.
C++ provides file handling through the fstream, ifstream, and ofstream classes, which are defined in the <fstream> header file.
Why Do We Need File Handling?
Let’s imagine a program that collects user details such as name, age, and address. If we don’t save the data to a file, it will be lost when the program closes.
With file handling, we can:
- Store user data permanently.
- Retrieve data later for processing.
- Maintain logs and reports.
- Handle large data efficiently.
- Communicate between programs using file-based data exchange.
In short, file handling enables data persistence — keeping data available beyond program execution.
File Handling in C++: The Basics
C++ provides three main classes for handling files:
- ofstream – Used for writing to files (output file stream).
- ifstream – Used for reading from files (input file stream).
- fstream – Used for both reading and writing.
All these classes are available in the <fstream>
header file.
Example:
#include <fstream>
using namespace std;
int main() {
ofstream file("data.txt");
file << "Hello File!";
file.close();
}
In this simple program:
ofstream file("data.txt");
creates and opens a file nameddata.txt
.file << "Hello File!";
writes text into the file.file.close();
closes the file after writing.
Including the fstream Library
Before performing any file operation, you must include the fstream library:
#include <fstream>
This library provides all necessary classes and functions for file management.
Opening and Closing Files
Before reading or writing, you need to open a file. Similarly, it’s good practice to close it after completing operations to free resources and ensure data is saved properly.
Syntax for Opening Files
fstream file;
file.open("filename", mode);
Syntax for Closing Files
file.close();
The mode
determines what operation will be performed (read, write, append, etc.).
File Opening Modes in C++
C++ provides several file opening modes, each specifying a particular way of handling files.
Mode | Description |
---|---|
ios::in | Open file for reading |
ios::out | Open file for writing |
ios::app | Append data to the end of the file |
ios::ate | Open file and move pointer to the end |
ios::trunc | Delete file contents if it exists |
ios::binary | Open file in binary mode |
You can combine modes using the bitwise OR (|
) operator.
Example:
file.open("data.txt", ios::out | ios::app);
This opens the file for both writing and appending.
Writing to a File (ofstream)
To write to a file, you use the ofstream class.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outfile("example.txt");
if (!outfile) {
cout << "File could not be created!";
return 1;
}
outfile << "Welcome to File Handling in C++" << endl;
outfile << "This is a file write example.";
outfile.close();
cout << "Data written successfully.";
return 0;
}
Explanation:
ofstream outfile("example.txt");
opens or creates a file.outfile <<
writes data to the file.outfile.close();
closes the file after writing.
After running this program, open the example.txt
file to see the text inside.
Reading from a File (ifstream)
To read from a file, use the ifstream class.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream infile("example.txt");
string line;
while (getline(infile, line)) {
cout << line << endl;
}
infile.close();
return 0;
}
Explanation:
ifstream infile("example.txt");
opens the file for reading.getline(infile, line)
reads each line from the file.- The loop continues until the end of the file.
Using fstream for Both Reading and Writing
The fstream class can perform both input and output operations on the same file.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream file("data.txt", ios::in | ios::out | ios::app);
if (!file) {
cout << "File not found or could not be opened!";
return 1;
}
file << "Adding more data to the file.\n";
file.close();
cout << "Data appended successfully.";
return 0;
}
This opens the file in both input and output modes and appends new data at the end.
Checking if a File Opened Successfully
Always check whether a file opened successfully before performing operations.
Example:
fstream file;
file.open("test.txt", ios::in);
if (!file) {
cout << "Error opening file!";
} else {
cout << "File opened successfully!";
}
file.close();
If the file does not exist, file
will evaluate as false
.
Writing and Reading Strings
You can store strings in files and read them back using getline()
.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outfile("names.txt");
outfile << "Alice\nBob\nCharlie";
outfile.close();
ifstream infile("names.txt");
string name;
while (getline(infile, name)) {
cout << "Name: " << name << endl;
}
infile.close();
return 0;
}
Output:
Name: Alice
Name: Bob
Name: Charlie
Writing and Reading Numbers
You can also handle numerical data using files.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream out("numbers.txt");
for (int i = 1; i <= 5; i++) {
out << i * 10 << endl;
}
out.close();
ifstream in("numbers.txt");
int num;
while (in >> num) {
cout << "Number: " << num << endl;
}
in.close();
return 0;
}
This program writes five numbers to a file and reads them back one by one.
Appending Data to an Existing File
To add new data at the end of an existing file without overwriting the current content, use the ios::app mode.
Example:
#include <fstream>
using namespace std;
int main() {
ofstream file("data.txt", ios::app);
file << "\nThis line is appended.";
file.close();
return 0;
}
Now, if data.txt
already has content, this code will add a new line to it instead of replacing the old content.
File Pointers and Random Access
Every file has two internal pointers:
- get pointer – for reading.
- put pointer – for writing.
You can move these pointers to read or write data at specific locations.
Functions for File Pointer Manipulation
Function | Description |
---|---|
seekg() | Move the get pointer (reading) |
seekp() | Move the put pointer (writing) |
tellg() | Returns the current get pointer position |
tellp() | Returns the current put pointer position |
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream file("example.txt", ios::in | ios::out);
file.seekp(0, ios::end);
cout << "Current write position: " << file.tellp() << endl;
file.seekg(0);
cout << "Current read position: " << file.tellg() << endl;
file.close();
return 0;
}
Working with Binary Files
Binary files store data in binary format rather than text format. They are faster and more efficient for large data or non-text data such as images or compiled code.
Writing to a Binary File
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream outfile("binary.dat", ios::binary);
int num = 12345;
outfile.write((char*)&num, sizeof(num));
outfile.close();
return 0;
}
Reading from a Binary File
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream infile("binary.dat", ios::binary);
int num;
infile.read((char*)&num, sizeof(num));
cout << "Number read: " << num;
infile.close();
return 0;
}
Reading and Writing Objects
You can store objects of a class in binary files.
Example:
#include <iostream>
#include <fstream>
using namespace std;
class Student {
public:
char name[20];
int age;
};
int main() {
Student s1 = {"John", 20};
ofstream outfile("student.dat", ios::binary);
outfile.write((char*)&s1, sizeof(s1));
outfile.close();
Student s2;
ifstream infile("student.dat", ios::binary);
infile.read((char*)&s2, sizeof(s2));
infile.close();
cout << "Name: " << s2.name << ", Age: " << s2.age;
return 0;
}
Checking End of File (EOF)
To detect the end of a file, use the eof()
function.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream file("example.txt");
string word;
while (!file.eof()) {
file >> word;
cout << word << " ";
}
file.close();
return 0;
}
Error Handling in File Operations
Sometimes, file operations fail due to reasons like:
- File not found.
- No permission.
- Disk full.
You can handle such errors using these functions:
fail()
– returns true if an operation fails.bad()
– returns true for irrecoverable errors.eof()
– checks for end of file.good()
– returns true if no error occurred.
Example:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream file("missing.txt");
if (file.fail()) {
cout << "Error: File not found or cannot be opened.";
} else {
cout << "File opened successfully.";
}
file.close();
return 0;
}
File Deletion and Renaming
C++ does not directly provide functions for deleting or renaming files, but you can use standard library functions.
Example: Renaming a File
rename("old.txt", "new.txt");
Example: Deleting a File
remove("data.txt");
File Handling and Structures
You can use file handling to store and retrieve structured data such as student records or employee details.
Example:
#include <iostream>
#include <fstream>
using namespace std;
struct Employee {
char name[30];
int id;
float salary;
};
int main() {
Employee e = {"Alice", 101, 55000.50};
ofstream out("employee.dat", ios::binary);
out.write((char*)&e, sizeof(e));
out.close();
Employee e2;
ifstream in("employee.dat", ios::binary);
in.read((char*)&e2, sizeof(e2));
in.close();
cout << "Name: " << e2.name << ", ID: " << e2.id << ", Salary: " << e2.salary;
return 0;
}
Advantages of File Handling
- Permanent Storage – Data remains available after program execution.
- Data Sharing – Multiple programs can use the same file.
- Large Data Handling – Easily manage large datasets.
- Data Recovery – Restore data even after a program crash.
- Automation – Useful for automated data logging and reporting.
Common Mistakes in File Handling
- Forgetting to close files.
- Not checking if a file opened successfully.
- Overwriting data unintentionally.
- Accessing files without proper modes.
- Misusing binary and text modes.
Always handle files carefully to prevent data loss or corruption.
Summary of Key Concepts
- Include
<fstream>
to handle files. - Use
ofstream
for writing andifstream
for reading. - Use
fstream
for both reading and writing. - Always close files after use.
- Check if a file opened successfully.
- Use
ios::app
,ios::out
,ios::in
, etc. to control file behavior. - Use binary mode for faster and more efficient storage.
- Handle errors using
fail()
,bad()
, andeof()
.
Final Example: Complete File Handling Program
#include <iostream>
#include <fstream>
using namespace std;
int main() {
string filename = "notes.txt";
// Write to file
ofstream writeFile(filename);
writeFile << "Learning File Handling in C++\n";
writeFile << "This file contains multiple lines.\n";
writeFile.close();
// Append to file
ofstream appendFile(filename, ios::app);
appendFile << "Appending more text at the end.\n";
appendFile.close();
// Read from file
ifstream readFile(filename);
string line;
cout << "File contents:\n";
while (getline(readFile, line)) {
cout << line << endl;
}
readFile.close();
return 0;
}
This complete example demonstrates writing, appending, and reading operations in one program.
Leave a Reply