Previous chapter: Chapter 17: Exception Handling: Robust Error Management in C++
Nearly every non-trivial application needs to persist data. This chapter covers File Input/Output (I/O) in C++ using the standard stream library (<fstream>), allowing programs to read data from disk files and write results back.
1. The C++ Stream Hierarchy
C++ manages I/O through a hierarchy of classes, all derived from std::ios:
std::ostream (Output Stream): Used for writing data (e.g., std::cout).
std::istream (Input Stream): Used for reading data (e.g., std::cin).
std::fstream (File Stream): The core header for file operations.
2. Writing Data to a File (std::ofstream)
The output file stream (std::ofstream) is used to write data to a file. It inherits the stream insertion operator (<<) from std::ostream.
#include <fstream>
#include <iostream>
void write_to_file(const std::string& filename) {
// 1. Create an ofstream object
std::ofstream output_file(filename);
// 2. Check if the file was successfully opened
if (output_file.is_open()) {
output_file << "This is the first line of C++ data." << std::endl;
output_file << 12345 << std::endl;
output_file.close(); // 3. Close the file when finished
std::cout << "Data written successfully." << std::endl;
} else {
std::cerr << "Unable to open file: " << filename << std::endl;
}
}
File Modes: You can specify file opening modes (e.g., std::ios::app for appending data) as a second argument to the constructor.
3. Reading Data from a File (std::ifstream)
The input file stream (std::ifstream) is used to read data from a file. It inherits the stream extraction operator (>>) from std::istream.
#include <fstream>
#include <string>
void read_from_file(const std::string& filename) {
std::ifstream input_file(filename);
std::string line;
if (input_file.is_open()) {
// Read the file line by line
while (std::getline(input_file, line)) {
std::cout << "Read: " << line << std::endl;
}
input_file.close();
} else {
std::cerr << "Unable to open file for reading." << std::endl;
}
}
4. Checking Stream Status
It's vital to check the state of a stream after an I/O operation to determine success or failure.
| State Flag | Description |
|---|
| .good() | Returns true if no errors have occurred. |
| .fail() | Returns true if a reading error or formatting failure occurred. |
| .eof() | Returns true if the end-of-file has been reached. |
| .bad() | Returns true if a non-recoverable I/O error occurred. |
A standard loop condition like while (input_file >> value) implicitly checks if the stream is in a good state, making it a clean way to read successive data items.