#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
using namespace std;
class A
{
char name[20];
int age;
public:
A(){}
A(const char* name,int age)
{
this->age =age;
if(name != NULL)
strcpy(this->name,name);
else strcpy(this->name,"none");
}
friend ostream& operator<<(ostream& os,A& a)
{
return os<<a.name<<" "<<a.age<<" ";
}
friend istream& operator>>(istream& is,A& a)
{
return is>>a.name>>a.age;
}
};
int main()
{
A s[5] = {A("leo",20),A("smith",19),A("tom",21),A("kelly",20),A("sam",18)};
ofstream fout("b.txt"); //这里打开文件,文件会截断成0。
if(!fout)
{
cout<<"fout error"<<endl;
return 0;
}
int i = 0;
while(i<5)
{
if(!fout) break;
fout.write((char*)&s[i],sizeof(s[i])); //用write写进去的话,是二进制格式。
i++;
}
//fout.flush();
ifstream fin("b.txt",ios::ate);//带开文件后立即定位在文件尾。我们用tellg得到的偏移量为文件的大小。
cout<<fin.tellg()<<endl;//输出0, 如果你将44行注释起来,就会输出0.这是因为你调用write()成员函数,只是写进缓冲区,而没有真正
//的写进文件里。这个时候你在ifstream打开,会以为是一个空文件。
fin.close();
ofstream fout1("c.txt");
if(!fout1)cout<<"fout1 error"<<endl;
i = 0;
while(i < 5)
{
fout1<<s[i]; //这种写进文件的格式,显示出来的是字符格式。你必须要自己定义<<,>>操作符重载函数。
//如果你将name的类型改为string类型时,由于sizoef(string) = 4.你用write写的话,只是将字符串的地址写进去了。在你读取的时候很可能崩溃。
//但是如果你用<<操作符写进去,则不会有什么问题。但是要注意,你必须自己设定正确的分割符。我在20行设定的是空格。这样才能保证在读取的时候是正确的。
i++;
}
fout1.flush();//同样要刷新流的缓冲区
fin.open("c.txt",ios::in);
if(!fin)
{
cout<<"fin error!"<<endl;
return 0;
}
A buf;
while(1)
{
fin>>buf; //这里同样是调用的是>>重载操作符函数。
if(fin.fail()) //我们在读取一次的时候就判断一次。
{
if(fin.eof()) //因为当读到EOF时,会设置failbit和eofbit,如果单单是failbit,则说明是读取中发生了错误。
break;
else{
cout<<"read failed"<<endl;
break;
}
}
cout<<buf;
}
}