文件操作
一、标准文件流读写(ifstream/ofstream)
必备头文件
必须引入 <fstream>(文件流核心头文件),配合 <iostream>、<string> 使用。
1. 写文件(ofstream)语法
核心格式
// 1. 创建写文件流对象,打开文件(不存在则创建,存在则清空原有内容)
ofstream 流对象名("文件路径/文件名");
// 2. 向文件写入内容,用法和cout完全一致
流对象名 << 要写入的内容 << endl;
// 3. 操作完成后关闭文件
流对象名.close();示例
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
// 打开test.txt,准备写入
ofstream fout("test.txt");
// 写入内容,换行用endl
fout << "Happy" << endl;
fout << "New Year";
// 关闭文件
fout.close();
return 0;
}2. 读文件(ifstream)语法
核心格式
// 1. 创建读文件流对象,打开已存在的文件
ifstream 流对象名("文件路径/文件名");
// 2. 读取文件内容,两种核心读取方式
// 方式1:>> 运算符,按空格/换行分隔读取,自动跳过空白符
流对象名 >> 变量;
// 方式2:getline函数,逐行读取,保留行内空格,读到换行符为止
getline(流对象名, 字符串变量);
// 3. 操作完成后关闭文件
流对象名.close();示例
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
// 打开test.txt,准备读取
ifstream fin("test.txt");
string s1, s2;
// >> 读取到第一个空白符(换行)为止
fin >> s1;
// getline 读取剩余整行
getline(fin, s2);
// 关闭文件
fin.close();
// 输出结果,对应真题第3题
cout << s1 << "|" << s2;
return 0;
}考点
- 写入对象必须匹配:必须用
ofstream创建的流对象(如fout)执行<<写入,不能用cout写入(错误写法:ofstream file("data.txt"); cout<<"Hello";无法写入文件,只会和往常一场输出在控制台)。 >>与getline的区别:>>以空格、换行、制表符为分隔符,读取后会残留换行符在缓冲区;getline读取整行,直到换行符为止,会吃掉换行符;>>后执行getline会读取>>后的换行符,导致无法正常输入数据。
>>读取数字的特性:自动跳过所有空格、换行符,无论内容是否分行,都能按顺序读取。- 逐行读取完整文件:
while (getline(流对象, line))可以循环读取文件的每一行,直到文件末尾。 - 文件关闭:文件操作完成后必须调用
close()关闭文件,避免资源泄漏。
二、C风格freopen 标准输入输出重定向
核心说明
通过freopen函数将标准输出流stdout(对应cout)、标准输入流stdin(对应cin) 重定向到指定文件,之后所有cin都会从该文件读取,cout输出的内容都会写入文件,而非屏幕。
必备头文件
必须引入 <cstdio>(freopen函数所在头文件),配合 <iostream> 使用。
核心语法格式
// 1. 重定向标准输出到文件:"w"代表写入模式,文件不存在则创建,存在则清空
freopen("文件路径/文件名", "w", stdout);
// 2. 重定向标准输入到文件:"r"代表读取模式,文件不存在则创建,存在则清空
freopen("文件路径/文件名", "r", stdin);
// 3. 正常使用cout输出,内容会写入文件,而非屏幕
// 4. 正常使用cin输入,会从文件读取内容,而非键盘
// 5. 操作完成后关闭文件,恢复标准输出
fclose(stdout);示例
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
// 将cout的输出重定向到log.txt
freopen("log.txt", "w", stdout);
// 此内容会写入log.txt,而非屏幕
cout << "Welcome to GESP!" << endl;
// 将cin的输入重定向到log.txt
freopen("log.txt", "r", stdin);
// 从log.txt读取字符串
string s;
cin >> s;
// 关闭文件
fclose(stdout);
return 0;
}考点
- 重定向后cout才生效:只有执行了
freopen重定向后,cout的内容才会写入文件,未重定向时cout只会输出到屏幕。 - 打开模式:写入文件必须用
"w"模式,代表只写、创建/清空文件。 - 必须关闭:重定向后必须用
fclose(stdout)关闭文件,刷新缓冲区,确保内容全部写入。
三、C++流缓冲区rdbuf 重定向
核心说明
通过修改cout的流缓冲区(rdbuf),将cout的输出目标切换到文件流,实现输出重定向,相比freopen更灵活,可随时恢复cout到屏幕输出。
必备头文件
必须引入 <fstream>、<iostream>,无需额外C语言头文件。
核心语法格式
// 1. 创建文件输出流,打开目标文件
ofstream 流对象名("文件路径/文件名");
// 2. 保存cout原有的屏幕缓冲区地址
streambuf* 原缓冲区名 = cout.rdbuf();
// 3. 将cout的缓冲区切换为文件流的缓冲区,后续cout输出到文件
cout.rdbuf(流对象名.rdbuf());
// 4. 正常使用cout输出,内容会写入文件
cout << 要写入的内容 << endl;
// 5. 操作完成后,恢复cout到原屏幕缓冲区
cout.rdbuf(原缓冲区名);
// 6. 关闭文件流
流对象名.close();示例
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
// 创建文件流,打开log.txt
ofstream log_file("log.txt");
// 保存cout原有的屏幕缓冲区
streambuf* org_cout = cout.rdbuf();
// 切换cout到文件缓冲区
cout.rdbuf(log_file.rdbuf());
// 内容写入log.txt
cout << "Happy Spring!" << endl;
// 恢复cout到屏幕输出
cout.rdbuf(org_cout);
// 关闭文件
log_file.close();
return 0;
}考点
- 必须保存原缓冲区:重定向前必须保存cout的原缓冲区地址,否则后续无法恢复cout到屏幕输出。
- 切换缓冲区后cout才生效:只有执行
cout.rdbuf(文件流.rdbuf())后,cout才会输出到文件,未切换时cout仅输出到屏幕。 - 必须恢复缓冲区:文件操作完成后,必须将cout的缓冲区恢复为原有值,避免后续cout无法正常输出到屏幕。
无效写入错误写法示例:
// 错误写法:仅创建文件流,但未修改cout的输出目标
ofstream outFile("log.txt");
cout << "Welcome to GESP!" << endl; // 内容仅输出到屏幕,不会写入文件
outFile.close();核心错误:创建了文件流,但既没有用文件流对象执行<<写入,也没有对cout做任何重定向,cout始终输出到屏幕,最终文件为空。
注意总共有三套语法体系,喜欢混起来考,分清楚每一种的流程
评论已关闭