with-open-file (File I/O)
C++ file I/O is performed using the three classes provided by the <fstream> header: ifstream (input), ofstream (output), and fstream (both). They work with the same << / >> operators as iostream, and the destructor handles file closing automatically so the file is safely closed when the object goes out of scope.
Syntax
// ========================================
// File I/O basic syntax
// ========================================
#include <fstream>
#include <string>
// --- Write to a file (ofstream) ---
// Creates the file if it doesn't exist, overwrites if it does
std::ofstream ofs("output.txt");
if (ofs.is_open()) { // Check if opened successfully
ofs << "Writing text to file" << std::endl;
}
// ofs goes out of scope and close() is called automatically
// --- Read from a file (ifstream) ---
std::ifstream ifs("output.txt");
std::string line;
while (std::getline(ifs, line)) { // Read line by line
// line contains the content of one line
}
// --- Read and write (fstream) ---
// Use std::ios::in | std::ios::out to specify mode
std::fstream fs("data.txt", std::ios::in | std::ios::out);
// --- Append mode (ofstream + app flag) ---
// Keeps existing content and appends to the end
std::ofstream ofs_app("log.txt", std::ios::app);
ofs_app << "Appended line" << std::endl;
Class and Flag Reference
| Class / Flag | Description |
|---|---|
| ifstream | Read-only file input stream. Open by passing a path to the constructor. |
| ofstream | Write-only file output stream. Creates or overwrites the file by default. |
| fstream | Read/write stream. Behavior is controlled by mode flags. |
| is_open() | Returns bool indicating whether the file was opened successfully. Use for error checking. |
| getline(stream, str) | Reads one line from the stream into str. The newline character is not included. |
| close() | Explicitly closes the stream. Called automatically when the object goes out of scope. |
| std::ios::app | Append mode. Adds data to the end of an existing file. |
| std::ios::trunc | Truncate mode. Empties the file contents on open (default for ofstream). |
| std::ios::binary | Binary mode. Reads and writes data without converting newline characters. |
| eof() / fail() / bad() | Member functions for checking stream state. Used to determine loop termination, etc. |
Sample Code
jujutsu_file_io.cpp
// ========================================
// jujutsu_file_io.cpp
// Writes Jujutsu Kaisen character data to a file
// and reads it back for display
// ========================================
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
struct Sorcerer {
std::string name;
int grade;
std::string ability;
};
void writeSorcerers(const std::string& filename, const std::vector<Sorcerer>& sorcerers) {
std::ofstream ofs(filename);
if (!ofs.is_open()) {
std::cerr << "Error: could not open file: " << filename << std::endl;
return;
}
ofs << "name,grade,ability" << std::endl;
for (int i = 0; i < (int)sorcerers.size(); i++) {
ofs << sorcerers[i].name << ","
<< sorcerers[i].grade << ","
<< sorcerers[i].ability << std::endl;
}
std::cout << "[Write complete] " << sorcerers.size()
<< " records written to " << filename << std::endl;
}
std::vector<Sorcerer> readSorcerers(const std::string& filename) {
std::vector<Sorcerer> result;
std::ifstream ifs(filename);
if (!ifs.is_open()) {
std::cerr << "Error: could not open file: " << filename << std::endl;
return result;
}
std::string line;
std::getline(ifs, line); // Skip header
while (std::getline(ifs, line)) {
if (line.empty()) { continue; }
std::istringstream ss(line);
std::string token;
Sorcerer s;
std::getline(ss, token, ','); s.name = token;
std::getline(ss, token, ','); s.grade = std::stoi(token);
std::getline(ss, token, ','); s.ability = token;
result.push_back(s);
}
std::cout << "[Read complete] " << result.size()
<< " records read from " << filename << std::endl;
return result;
}
void appendLog(const std::string& logFile, const std::string& message) {
std::ofstream ofs(logFile, std::ios::app);
if (!ofs.is_open()) {
std::cerr << "Error: could not open log file." << std::endl;
return;
}
ofs << message << std::endl;
}
int main() {
const std::string dataFile = "sorcerers.csv";
const std::string logFile = "battle_log.txt";
std::vector<Sorcerer> team;
team.push_back({"Itadori Yuji", 1, "Divergent Fist / Black Flash"});
team.push_back({"Fushiguro Megumi",2, "Ten Shadows Technique"});
team.push_back({"Kugisaki Nobara", 3, "Straw Doll Technique"});
team.push_back({"Gojo Satoru", 0, "Limitless / Hollow Purple"});
team.push_back({"Nanami Kento", 1, "Ratio Technique"});
writeSorcerers(dataFile, team);
std::cout << std::endl;
std::vector<Sorcerer> loaded = readSorcerers(dataFile);
std::cout << std::endl;
std::cout << "=== Sorcerer Data ===" << std::endl;
for (int i = 0; i < (int)loaded.size(); i++) {
std::cout << " Name: " << loaded[i].name
<< " Grade: ";
if (loaded[i].grade == 0) {
std::cout << "Special";
} else {
std::cout << loaded[i].grade;
}
std::cout << " Technique: " << loaded[i].ability << std::endl;
}
std::cout << std::endl;
appendLog(logFile, "--- Battle start ---");
appendLog(logFile, "Itadori vs Mahito: Itadori used Black Flash.");
appendLog(logFile, "Gojo vs Jogo: Gojo used Hollow Purple.");
appendLog(logFile, "--- Battle end ---");
std::cout << "[Append complete] Log written to " << logFile << std::endl;
std::cout << std::endl;
std::cout << "=== Battle Log ===" << std::endl;
std::ifstream logIfs(logFile);
if (logIfs.is_open()) {
std::string logLine;
while (std::getline(logIfs, logLine)) {
std::cout << " " << logLine << std::endl;
}
}
return 0;
}
g++ -std=c++11 jujutsu_file_io.cpp -o jujutsu_file_io ./jujutsu_file_io [Write complete] 5 records written to sorcerers.csv [Read complete] 5 records read from sorcerers.csv === Sorcerer Data === Name: Itadori Yuji Grade: 1 Technique: Divergent Fist / Black Flash Name: Fushiguro Megumi Grade: 2 Technique: Ten Shadows Technique Name: Kugisaki Nobara Grade: 3 Technique: Straw Doll Technique Name: Gojo Satoru Grade: Special Technique: Limitless / Hollow Purple Name: Nanami Kento Grade: 1 Technique: Ratio Technique [Append complete] Log written to battle_log.txt === Battle Log === --- Battle start --- Itadori vs Mahito: Itadori used Black Flash. Gojo vs Jogo: Gojo used Hollow Purple. --- Battle end ---
Common Mistake 1: Skipping the is_open() check
If a file cannot be opened due to a missing file or insufficient permissions, reading or writing without checking is_open() silently does nothing, creating hard-to-diagnose bugs.
// NG: Writing without checking is_open()
std::ofstream ofs("/root/restricted.txt");
ofs << "Gojo's memo" << std::endl; // If open failed, nothing is written (no error)
OK: Always check is_open() after opening.
// OK: Check is_open() before accessing
std::ofstream ofs("memo.txt");
if (!ofs.is_open()) {
std::cerr << "Error: could not open file." << std::endl;
return 1;
}
ofs << "Gojo's memo" << std::endl;
g++ -std=c++11 file_open_check.cpp -o file_open_check ./file_open_check Error: could not open file.
Common Mistake 2: Opening a binary file in text mode
On Windows, text mode converts \n (LF) to \r\n (CRLF). Opening a binary file such as an image or audio file in text mode corrupts the data.
// NG: Opening a binary file in text mode (corrupts data on Windows)
std::ofstream ofs("image.png");
ofs.write(binaryData, dataSize); // \n converted to \r\n, data is corrupted
OK: Add the std::ios::binary flag.
// OK: Open in binary mode
std::ofstream ofs("image.png", std::ios::binary);
ofs.write(binaryData, dataSize); // No conversion, data written exactly
g++ -std=c++11 binary_write.cpp -o binary_write ./binary_write Binary file write complete: 1024 bytes
Overview
C++ file I/O uses ifstream, ofstream, and fstream provided by the <fstream> header. These follow the RAII (Resource Acquisition Is Initialization) principle — the file is automatically closed when the object goes out of scope, preventing resource leaks from forgetting to close it. Checking with is_open() after opening a file is a commonly used pattern. For text mode, reading line by line with getline() is the safe and general approach. When appending is needed, specify the std::ios::app flag. For binary files such as images or audio, add the std::ios::binary flag to suppress OS-level newline conversion. Cross-reference: string / class
If you find any errors or copyright issues, please contact us.