C++ file I/O | ifstream, ofstream, and binary reads/writes
이 글의 핵심
Hands-on guide to ofstream/ifstream, ios::app and ios::binary, checking is_open, line-by-line reading, and when to use filesystem paths for Unicode names.
Writing files (ofstream)
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream file("output.txt");
if (!file.is_open()) {
cout << "Failed to open file" << endl;
return 1;
}
file << "Hello, World!" << endl;
file << "C++ file I/O" << endl;
file.close();
cout << "File saved" << endl;
return 0;
}
Reading files (ifstream)
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
ifstream file("input.txt");
if (!file.is_open()) {
cout << "Failed to open file" << endl;
return 1;
}
string line;
while (getline(file, line)) {
cout << line << endl;
}
file.close();
return 0;
}
File modes
// overwrite
ofstream file1("file.txt");
// append
ofstream file2("file.txt", ios::app);
// read
ifstream file3("file.txt");
// read + write
fstream file4("file.txt", ios::in | ios::out);
// binary
ofstream file5("file.bin", ios::binary);
Practical examples
Example 1: Read CSV
#include <fstream>
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
struct Student {
string name;
int age;
double score;
};
vector<Student> readCSV(const string& filename) {
vector<Student> students;
ifstream file(filename);
if (!file.is_open()) {
cout << "Failed to open file" << endl;
return students;
}
string line;
getline(file, line); // skip header
while (getline(file, line)) {
stringstream ss(line);
Student s;
string token;
getline(ss, s.name, ',');
getline(ss, token, ',');
s.age = stoi(token);
getline(ss, token, ',');
s.score = stod(token);
students.push_back(s);
}
file.close();
return students;
}
int main() {
vector<Student> students = readCSV("students.csv");
for (const auto& s : students) {
cout << s.name << ", age " << s.age << ", score " << s.score << endl;
}
return 0;
}
CSV parsing appears in many real systems.
Example 2: Log file
#include <fstream>
#include <iostream>
#include <ctime>
using namespace std;
class Logger {
private:
ofstream logFile;
string getCurrentTime() {
time_t now = time(0);
char buf[80];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&now));
return string(buf);
}
public:
Logger(const string& filename) {
logFile.open(filename, ios::app);
}
~Logger() {
if (logFile.is_open()) {
logFile.close();
}
}
void info(const string& message) {
logFile << "[" << getCurrentTime() << "] [INFO] "
<< message << endl;
}
void error(const string& message) {
logFile << "[" << getCurrentTime() << "] [ERROR] "
<< message << endl;
}
};
int main() {
Logger logger("app.log");
logger.info("program start");
logger.info("loading data...");
logger.error("file not found");
logger.info("program exit");
return 0;
}
Logging to files is essential in most applications.
Example 3: Binary struct I/O
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct GameSave {
int level;
int score;
int lives;
char playerName[50];
};
void saveGame(const string& filename, const GameSave& save) {
ofstream file(filename, ios::binary);
file.write(reinterpret_cast<const char*>(&save), sizeof(GameSave));
file.close();
cout << "Game saved" << endl;
}
GameSave loadGame(const string& filename) {
GameSave save{};
ifstream file(filename, ios::binary);
if (file.is_open()) {
file.read(reinterpret_cast<char*>(&save), sizeof(GameSave));
file.close();
cout << "Game loaded" << endl;
}
return save;
}
int main() {
GameSave save{};
save.level = 10;
save.score = 5000;
save.lives = 3;
strcpy(save.playerName, "Player1");
saveGame("save.dat", save);
GameSave loaded = loadGame("save.dat");
cout << "level: " << loaded.level << endl;
cout << "score: " << loaded.score << endl;
cout << "lives: " << loaded.lives << endl;
cout << "name: " << loaded.playerName << endl;
return 0;
}
Binary serialization of POD-like structs—mind endianness and versioning in production.
Common pitfalls
Pitfall 1: Not checking open
Symptom: Empty reads on missing files.
Cause: Skipping is_open().
ifstream file("nonexistent.txt");
if (!file.is_open()) {
cerr << "Failed to open file" << endl;
return 1;
}
Pitfall 2: Forgetting to flush/close
Symptom: Truncated output on crash.
Fix: close(), or rely on scope; understand flush when mixing streams.
{
ofstream file("output.txt");
file << "data";
}
Pitfall 3: Text vs binary
Symptom: Corrupt numeric data on Windows.
Fix: Open with ios::binary for raw structs.
ofstream file("data.bin", ios::binary);
FAQ
Q1: Test if a file exists?
A: Try opening it or use std::filesystem::exists.
bool fileExists(const string& filename) {
ifstream file(filename);
return file.is_open();
}
Q2: Read entire file into a string?
A:
#include <fstream>
#include <sstream>
string readFile(const string& filename) {
ifstream file(filename);
stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
Q3: File size?
A: seekg/tellg (binary mode avoids text quirks).
ifstream file("file.txt", ios::binary);
file.seekg(0, ios::end);
size_t size = file.tellg();
file.seekg(0, ios::beg);
Q4: Large files?
A: Read line by line or in chunks.
ifstream file("large.txt");
string line;
while (getline(file, line)) {
}
Q5: Non-ASCII paths?
A: Use std::filesystem::path and wide APIs where required on Windows.
#include <filesystem>
namespace fs = std::filesystem;
fs::path p = U"path/with/unicode"; // platform-specific helpers as needed
Q6: Multiple files at once?
A: Use separate stream objects.
ifstream file1("input1.txt");
ifstream file2("input2.txt");
ofstream output("output.txt");
Related posts (internal)
- C++ file operations deep dive
- C++ file I/O basics
- C++ operator overloading
Practical tips
Debugging
- Enable warnings.
- Reproduce with tiny files.
Performance
- Profile before optimizing.
Code review
- Follow team conventions.
Production checklist
Before coding
- Right tool?
- Maintainable?
- Meets I/O requirements?
While coding
- Warnings cleared?
- Edge cases covered?
At review
- Intent clear?
- Tests sufficient?
Keywords
C++, file I/O, ifstream, ofstream, fstream
Related posts
- C++ series
- C++ Adapter Pattern
- C++ ADL |
- C++ Aggregate Initialization |