C++ 文件输入输出库 – 的入门与实战
在 C++ 编程中,处理数据的方式远不止在控制台打印或读取键盘输入。很多时候,我们需要将程序运行的数据持久化保存到磁盘文件中,或者从文件中加载数据进行处理。这时,C++ 提供的文件输入输出库 —— <fstream> 就成了不可或缺的工具。
这个库是标准库的一部分,提供了 ifstream(输入文件流)、ofstream(输出文件流)和 fstream(双向文件流)三种核心类,让你可以像操作 cin 和 cout 一样,轻松地读写文件内容。虽然初学者可能会觉得文件操作复杂,但只要掌握基本逻辑,你会发现它其实非常直观。
文件流的核心概念:流与文件的“桥梁”
想象一下,文件就像一个图书馆里的书本,而程序则是读者。<fstream> 就是那个连接你和书本之间的“阅读器”。它把文件的内容变成一串连续的“数据流”,你可以从中读取,也可以向其中写入。
在 C++ 中,ifstream 用于从文件读取数据,ofstream 用于向文件写入数据,而 fstream 可以同时支持读和写。它们都继承自 iostream,因此你熟悉的 >> 和 << 操作符依然可用。
⚠️ 提示:使用文件流前,必须包含头文件
<fstream>。
从零开始:创建与写入文件
我们先来一个最简单的例子:创建一个文本文件,并写入几行文字。
#include <iostream>
#include <fstream>
#include <string>
int main() {
// 创建一个 ofstream 对象,指定文件名为 "output.txt"
std::ofstream outFile("output.txt");
// 检查文件是否成功打开
if (!outFile.is_open()) {
std::cerr << "文件打开失败!" << std::endl;
return 1;
}
// 使用 << 操作符向文件写入内容
outFile << "第一行:Hello, C++ File I/O!" << std::endl;
outFile << "第二行:这是通过 <fstream> 写入的文本。" << std::endl;
outFile << "第三行:文件操作其实很简单。" << std::endl;
// 关闭文件,释放资源
outFile.close();
std::cout << "文件写入成功!" << std::endl;
return 0;
}
代码解析:
std::ofstream outFile("output.txt");:创建一个输出文件流,尝试打开output.txt。如果文件不存在,会自动创建。!outFile.is_open():检查文件是否成功打开。这是防止程序因文件无法访问而崩溃的重要步骤。outFile << ...:使用输出操作符写入数据,和cout用法几乎一样。outFile.close();:必须显式关闭文件,否则可能造成数据丢失或资源泄漏。
💡 小贴士:如果你在 IDE 中运行这段代码,运行后会发现项目目录下多了一个
output.txt文件,打开就能看到写入的内容。
读取文件内容:从磁盘“取书”
现在我们来读取刚才创建的文件。这次用 ifstream。
#include <iostream>
#include <fstream>
#include <string>
int main() {
// 创建输入文件流,打开 "output.txt"
std::ifstream inFile("output.txt");
// 检查文件是否打开成功
if (!inFile.is_open()) {
std::cerr << "文件打开失败!" << std::endl;
return 1;
}
std::string line;
int lineNumber = 1;
// 逐行读取文件内容
while (std::getline(inFile, line)) {
std::cout << "第 " << lineNumber << " 行: " << line << std::endl;
lineNumber++;
}
// 关闭文件
inFile.close();
return 0;
}
代码解析:
std::getline(inFile, line):这是读取文件的“神器”函数。它会读取一行内容(直到换行符),并存入line字符串中。while (std::getline(...)):循环直到文件读完。当文件结束时,getline会返回false,循环自动退出。- 与
>>不同,getline会保留空格和换行符,适合处理整行文本。
读写混合:使用 fstream 实现双向操作
有时候你需要同时读和写同一个文件。比如修改配置文件、日志追加等。这时 fstream 就派上用场了。
#include <iostream>
#include <fstream>
#include <string>
int main() {
// 使用 fstream 实现读写功能
std::fstream file("config.txt", std::ios::in | std::ios::out | std::ios::app);
if (!file.is_open()) {
std::cerr << "文件打开失败!" << std::endl;
return 1;
}
// 先写入新内容(追加模式)
file << "last_update=2024-04-05" << std::endl;
// 将文件指针重置到开头,准备读取
file.seekg(0, std::ios::beg);
std::string line;
std::cout << "文件当前内容:" << std::endl;
// 读取并输出所有行
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
file.close();
return 0;
}
关键点说明:
std::ios::app:追加模式,写入内容会加在文件末尾。file.seekg(0, std::ios::beg):将“读指针”移动到文件开头。seekg是“seek get”的缩写,用于控制读位置。std::ios::in | std::ios::out:同时启用读和写权限。
✅ 这种方式适合日志记录、配置文件更新等场景。
文件模式详解:选择正确的打开方式
打开文件时,你可以指定不同的模式,决定文件行为。以下是常见模式组合:
| 模式标志 | 作用 |
|---|---|
std::ios::in |
以只读方式打开文件(默认) |
std::ios::out |
以写入方式打开文件,若文件存在则清空内容 |
std::ios::app |
以追加方式打开,写入内容添加到文件末尾 |
std::ios::ate |
打开文件后立即定位到文件末尾 |
std::ios::binary |
以二进制模式打开,用于处理非文本文件(如图片、音频) |
📌 示例:
std::fstream file("data.bin", std::ios::in | std::ios::binary);用于读取二进制文件。
实际应用:保存用户信息到文件
我们来做一个更实用的小项目:保存用户信息到文件。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
struct User {
std::string name;
int age;
std::string email;
};
int main() {
std::vector<User> users = {
{"张三", 25, "zhangsan@example.com"},
{"李四", 30, "lisi@example.com"},
{"王五", 22, "wangwu@example.com"}
};
// 写入用户数据到文件
std::ofstream outFile("users.txt");
if (!outFile.is_open()) {
std::cerr << "无法创建文件!" << std::endl;
return 1;
}
for (const auto& user : users) {
outFile << user.name << " " << user.age << " " << user.email << std::endl;
}
outFile.close();
std::cout << "用户信息已保存到 users.txt" << std::endl;
// 读取并显示
std::ifstream inFile("users.txt");
if (!inFile.is_open()) {
std::cerr << "无法打开文件!" << std::endl;
return 1;
}
std::string name;
int age;
std::string email;
std::cout << "\n读取到的用户信息:" << std::endl;
while (inFile >> name >> age >> email) {
std::cout << "姓名: " << name << ", 年龄: " << age << ", 邮箱: " << email << std::endl;
}
inFile.close();
return 0;
}
亮点分析:
- 使用结构体封装用户数据,代码更清晰。
- 用
>>操作符按空格分割读取,适合格式固定的文本。 - 实际项目中,这种数据持久化方式非常常见。
总结与建议
通过本文,我们系统地学习了 C++ 文件输入输出库 —— <fstream> 的核心用法。从最基础的文件创建与写入,到读取、混合读写,再到实际项目中的应用,每一步都围绕“如何让程序与文件对话”展开。
✅ 关键提醒:
- 每次使用文件流前,务必检查
is_open()。- 写完文件后,一定要调用
close()。- 选择正确的打开模式,避免意外覆盖或追加错误。
<fstream> 虽然看似简单,但它是构建完整应用程序的重要一环。无论是保存用户数据、读取配置、生成报告,还是处理日志,它都能胜任。
掌握它,你就迈出了让程序“有记忆”的第一步。别再只让程序在内存中“活一瞬”,而是让它真正“活”在你的电脑里。