文件的读写操作2

这篇接着上篇,介绍C++的文件读写操作,可能大家发现,每次运行程序后,新写入的数据将会把以前的数据覆盖掉。有时并不希望这样,而是希望将新的数据追加到文件的结尾。要完成这样的功能,就必须了解C++的文件读写模式。C++的ios_base类定义了一些文件模式常量,用以控制文件将如何被使用。下面列出了一些常见的文件模式常量,它是bitmask类型的,也就意味着可以用或运算对其进行模式叠加。

文件模式常量
ios_base::in 供读
ios_base::out 供写
ios_base::app 追加到文件尾
ios_base::trunc 若文件存在,则截短文件
ios_base::binary 二进制文件

从上述表格中可以看出,ofstream对象默认的文件打开格式应该是ios_base::out | ios_base::trunc,而ifstream对象默认的文件打开格式是iso_base::in。事实上,open方法提供了第二个参数可供修改文件的打开模式。如可使用

	
        ofstream fout
        fout.open(fileName,ios_base::out|ios_base::app);

将文件模式设置为打开以写入,追加模式,这样就可以将新的数据追加到文件的结尾。当然也可以像上篇一样使用构造对文件模式进行设置,下文中的例子就采用了下面的方法

	ofstream fout(fileName,ios_base::out|ios_base::app);
对文件的打开模式进行设置。
例子中使用了一个结构体,对输入数据进行存取。将数据存储到文件中,一般来说有两种方法:文本格式或二进制格式。文本格式是将所有内容,包括数字,都存储为文本,如,double型的12.3将存储为4个字符。二进制格式直接存储的是计算机的内部表示,也就是说若采用此种方法12.3将会被存储为这个值的64位(不同系统可能不一样)表示。对字符来说,二进制表示与文本表示是一样的,即字符的ASCII码的二进制表示。对数字来说,会有很大差异,一般会显示问乱码,如果打开的话。下面的例子将会看到这个效果。
#include <iostream>
#include <fstream>
using namespace std;

struct testStruct 
{
	char name[20];
	double scores;
};
int main()
{
	const char* fileName = "1.txt";
	ofstream fout(fileName,ios_base::out|ios_base::app|ios_base::binary);//采用追加模式,以二进制写入到文件
	testStruct t;
	if (!fout.is_open())
	{
		cerr<<"Can't open "<<fileName<<endl;
		exit(EXIT_FAILURE);
	}
	cin.get(t.name,20);
	cin>>t.scores;
	fout.write((char*)&t,sizeof(t));
	fout.close();
	fout.clear();
	ifstream fin(fileName,ios_base::in|ios_base::binary);//以二进制读取
	while (fin.read((char*)&t,sizeof(t)))//每次读出一个testStruct数据,存放在t中,直到文件尾
	{
		cout<<t.name<<": "<<t.scores<<endl;
	}
	fin.close();
	fin.clear();
	return 0;
}
 
 

程序的运行结果如下:


说明:nihao和wohao的那两条数据是先前添加进去的,利用write和read函数对内存中的内容直接进行复制,而不进行任何转换,如它将double值中的8个字节(不同系统可能不同)直接复制,而不会将其转化为文本。唯一不便的是,它传入的地址必须是char*型的,很多时候需要进行转换。read和write函数是一对相反的过程,第一个参数代表起始地址,第二个参数代表从起始位置开始复制多少个字节。值得一提的是上面例子中的name不能声明为string对象,至少在程序不做重大修改前是不可以的。原因在于:string类型的对象实际上并没有包含字符串,而是包含了一个指向其中存储了字符串的内存单元的地址。因此,将结构复制到文件中时,复制的不是字符串而是地址。运行程序进行读取数据时,该地址无意义,而且程序很可能死掉。但是以文本方式进行存储时则不会发生此种现象。

存入的二进制文件如下图,大家可以看到字符类型的没有乱码,而double类型的为乱码。


本人才疏学浅,其中若有错误,欢迎指正,不胜感激。

TO BE CONTINUED!

猜你喜欢

转载自blog.csdn.net/zhuyinglong2010/article/details/46423243