C++ 深究fstream打开方式ios::app,ios::ate,ios::in,ios::out

本文探讨了使用C++进行文件写入时,如何避免覆盖原有内容并实现追加写入的方法。通过对比不同打开模式如默认模式、ios::app、ios::ate以及组合模式ios::ate|ios::in的效果,详细解析了每种模式下文件写入的行为差异。最终,通过深入理解枚举类型与二进制位运算,得出了一种通用的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 学习资料

资料1:C++ 文件和流
资料2:ofstream之ios::ate,ios::app,ios::in,ios::out

2 学习思路

2.1 所需实现功能

实现网页1所说的写入姓名与年龄功能,但是稍作修改,分两次打开文件,第一次写入姓名,第二次写入年龄。

2.2 第一次尝试 默认

#include<fstream>
#include<iostream>
using namespace std;
int main()
{
	char data[100];
	
	//第一次打开文件
	ofstream outfile;
	outfile.open("D:\\afile.dat");
	cout << "Writing to the file" << endl;
	cout << "Enter your name:";
	cin.getline(data, 100);
	outfile << data << endl;
	outfile.close();
	
	//第二次打开文件
	ofstream outfile2;
	outfile2.open("D:\\afile.dat");//**待修改语句**
	cout << "Enter your age:";
	cin >> data;
	outfile2 << data << endl;
	outfile2.close();//第二次关闭文件
	
	return 0;
}

输入:
Wu Mingtang
25
输出文件内容为:
默认打开
第一次打开文件写入的姓名内容没有了,说明默认方式打开会覆盖原始文件。

2.3 第二次尝试 ios::app

根据资料1所说,使用ios::app模式进行第二次打开,即将待修改语句改为:

	outfile2.open("D:\\afile.dat", ios::app);

运行结果为:
打开模式为ios::app
结果满足预期,说明ofstream对象使用ios::app模式打开文件可以在文件末尾添加新内容。

2.4 第三次尝试 ios::ate

根据资料1所说,ios::ate可以定位到文件末尾,是否可以直接使用该模式打开文件,直接在文件末尾添加新内容?
代码修改为:

	outfile2.open("D:\\afile.dat", ios::ate);

输出文件为:
ios::ate模式打开结果
说明,以上思路行不通,ios::ate并不能直接在文件尾进行写入操作。

2.5 第四次尝试 ios::ate|ios::in

根据资料2所说,可以使用ios::ate|ios::in模式打开,代码修改为:

	outfile2.open("D:\\afile.dat", ios::ate|ios::in);

输出文件内容为:
ios::ate|ios::in模式打开
可见ios::ate|ios::in模式与ios::app模式效果一致。

2.6 第五次尝试 0x05

  • 看到操作符“|”就很容易想到这是利用位“或”进行的计算,因此其本质应该是二进制数的“或”操作。
  • 转到ios::in的定义,其源代码为:
	static constexpr _Openmode in = (_Openmode)0x01;
	static constexpr _Openmode out = (_Openmode)0x02;
	static constexpr _Openmode ate = (_Openmode)0x04;
	static constexpr _Openmode app = (_Openmode)0x08;
	static constexpr _Openmode trunc = (_Openmode)0x10;

说明每一种模式是一个由二进制数转化为_Openmode类型的常量

  • _Openmode类型定义为为:
	enum _Openmode
		{	// constants for file opening options
		_Openmask = 0xff};
  • open函数接收的参数就是openmode变量:
	void open(const char *_Filename,
		ios_base::openmode _Mode = ios_base::out,
		int _Prot = (int)ios_base::_Openprot)
  • openmode类型其实就是int型
	typedef int openmode;
  • 归根结底,输出模式其实就是一个int型的变量,只是被各种包装掩盖了其真实面目,因此根据ios::ate|ios::in = 0x05,可以推知将0x05作为open()函数的参数,可以得到同样的结果。
  • 修改代码为:
	outfile2.open("D:\\afile.dat", 0x05);
  • 输出文件为:
    0x05
    可见结果与使用ios::app或者ios::ate|ios::in一致,上面的推论没有问题。

小问题

为什么枚举类型值可以和定义的不一样,基础知识有点不牢固,望各位赐教。

	enum _Openmode
		{	// constants for file opening options
		_Openmask = 0xff};
	static constexpr _Openmode in = (_Openmode)0x01;
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值