C++文件流操作详解:从文本读写到二进制拷贝
C++标准库提供了强大的文件处理能力,核心在于使用 fstream 及其派生类 ifstream(输入/读取)和 ofstream(输出/写入)。本文将通过具体实例,演示如何创建并写入文本文件、读取并显示其内容,以及如何利用二进制模式实现文件的高效拷贝,详细解析打开模式、错误处理及随机访问等关键操作。
结果或目标:实现基础文件读写
要完成文件的读写,首先需要明确使用的类对象。在C++中,fstream 是基类,ifstream 专用于读取,ofstream 专用于写入。对于大多数文本处理场景,直接使用对应的流对象能简化代码逻辑。
第1步:创建并写入文本文件
目的:向指定路径的文件中写入格式化的文本信息。
入口:包含头文件 #include <fstream> 和 #include <iomanip>(如需setw格式化)。
//创建一个文本文件并写入信息
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
void main()
{
ofstream f1("d:\\me.txt"); // 以输出模式打开文件,若不存在则创建
if(!f1)
{
cout<<"File open failed!"<<endl;
return;
}
// 使用插入运算符写文件内容,配合setw设置字段宽度
f1<<setw(20)<<"姓名:"<<"廉东方"<<endl;
f1<<setw(20)<<"家庭地址:"<<"河南郑州"<<endl;
f1.close(); // 必须关闭文件以保存数据
}
运行上述代码后,打开 d:\me.txt,将看到如下内容(注意空格对齐效果由setw控制):
姓名: 廉东方
家庭地址: 河南郑州
注意:路径中的反斜杠需要双写转义,例如 "D:\\MyFiles\\ReadMe.txt"。
第2步:显示文本文件内容
目的:将磁盘上的文本文件内容读取到控制台屏幕显示。
操作方式:可使用 get() 逐个字符读取,或使用 getline() / read() 批量读取。
方案一:逐字符读取
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
ifstream fin("d:\\简介.txt", ios::nocreate); // nocreate表示文件不存在时不自动创建,防止误建
if(!fin)
{
cout<<"File open error!\n";
return;
}
char c;
while((c=fin.get())!=EOF) // 判断是否读到文件末尾
{
cout<<c;
}
fin.close();
}
方案二:按块读取(利用 \0 终止符)
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
ifstream fin("d:\\简介.txt", ios::nocreate);
if(!fin)
{
cout<<"File open error!\n";
return;
}
char c[80];
// 巧妙利用文本文件中通常没有 '\0' 的特点,一次性读取直到遇到空字符或满80字节
while(fin.get(c, 80, '\0') != NULL)
{
cout<<c;
}
fin.close();
}
方案三:使用 read/write 配合 gcount()
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
ifstream fin("d:\\简介.txt", ios::nocreate);
if(!fin)
{
cout<<"File open error!\n";
return;
}
char c[80];
while(!fin.eof()) // 检测文件结束标志
{
fin.read(c, 80); // 尝试读取80字节
cout.write(c, fin.gcount()); // 仅输出实际读取到的字节数
}
fin.close();
}
第3步:二进制文件拷贝与注意事项
目的:实现任意类型文件(如图片、exe程序)的精确复制。 风险提醒:直接覆盖目标文件前请确保备份,避免数据丢失。
二进制操作与文本操作有显著区别,必须严格指定 ios::binary 模式,否则换行符等控制字符可能被转换,导致文件损坏。
#include<iostream>
#include<fstream>
using namespace std;
void main()
{
// 以二进制只读方式打开源文件
ifstream fin("C:\\1.exe", ios::nocreate | ios::binary);
if(!fin)
{
cout<<"Source file open error!\n";
return;
}
// 以二进制写入方式创建目标文件
ofstream fout("C:\\2.exe", ios::binary);
char c[1024];
while(!fin.eof())
{
fin.read(c, 1024);
fout.write(c, fin.gcount()); // 写入实际读取的字节数
}
fin.close();
fout.close();
cout<<"Copy over!\n";
}
准备条件:打开模式与文件状态
在使用 fstream 之前,了解打开模式参数至关重要。这些参数决定了文件是否存在时被如何处理,以及读写权限。
常见的打开方式选项
| 常量 | 含义 | 默认关联 |
|---|---|---|
ios::in | 供读取,文件不存在则报错(除非结合其他标志) | ifstream 默认 |
ios::out | 供写入,文件存在则清空原内容;不存在则创建 | ofstream 默认 |
ios::ate | 打开后将指针置于文件末尾,可随时移动 | 常与 in/out 联合使用 |
ios::app | 追加写入,所有写入操作自动定位到文件末尾 | 不影响指针位置查看 |
ios::trunc | 在读写前截断文件长度为0(ios::out 默认携带) | - |
ios::binary | 二进制模式,禁止文本模式下的换行符转换 | 必须手动指定 |
此外,还有 ios::nocreate(文件不存在时失败)和 ios::noreplace(文件存在时失败)等控制标志,可用于增强程序的健壮性。
检查文件打开成功与否
打开文件后,必须验证状态。虽然构造函数可以检查,但使用成员函数更规范:
if(f):对ifstream/ofstream有效,重载了bool运算符。if(f.good()):通用方法,表示无错误发生。if(!f)或if(f.fail()):表示打开失败或读写出错。
关闭与清理
显式调用 f.close(); 是最安全的做法。当对象生命周期结束时,析构函数会自动检查并关闭未关闭的文件流,但在涉及资源敏感的操作中,建议尽早手动关闭。
完成判断:随机读写与总结
除了顺序读写,C++还支持随机定位。通过移动内部指针,可在文件任意位置进行操作。
- 输入流指针:
seekg(绝对位置)或seekg(相对位置, 参照位置);当前位置可用tellg()获取。 - 输出流指针:
seekp(绝对位置)或seekp(相对位置, 参照位置);当前位置可用tellp()获取。 - 参照位置:
ios::beg(文件头,值0),ios::cur(当前位置,值1),ios::end(文件尾,值2)。
综上所述,掌握 <fstream> 的核心在于理解三类流对象的分工、正确组合打开模式(特别是二进制标志),以及善用状态检查和指针移动功能。遵循以上操作顺序与规范,即可稳健地完成各类文件处理任务。
以上就是C++文件流读写操作实例程序讲解的详细内容,更多关于C++文件处理技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









