理解C++ fstream的打开方式:ios::app, ios::ate, ios::in和ios::out-2的学习路径
最编程
2024-01-14 17:07:32
...
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);
运行结果为:
结果满足预期,说明ofstream对象使用ios::app模式打开文件可以在文件末尾添加新内容。
2.4 第三次尝试 ios::ate
根据资料1所说,ios::ate可以定位到文件末尾,是否可以直接使用该模式打开文件,直接在文件末尾添加新内容?
代码修改为:
outfile2.open("D:\\afile.dat", 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::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);
- 输出文件为:
可见结果与使用ios::app或者ios::ate|ios::in一致,上面的推论没有问题。
小问题
为什么枚举类型值可以和定义的不一样,基础知识有点不牢固,望各位赐教。
enum _Openmode
{ // constants for file opening options
_Openmask = 0xff};
static constexpr _Openmode in = (_Openmode)0x01;