ep9_12.cpp
上传用户:wxcui2006
上传日期:2022-07-12
资源大小:1274k
文件大小:5k
- /*9.12 将学校里的学生,定义为一个学生数组类,数组对象动态建立,初始为3个元素,不够用时扩充
- 一倍。要求放在构造函数中用二进制数据文件建立数组元素对象,在析构函数中保存数据和关闭文件。
- 第一次运行时,建立空的数据文件,由键盘输入建立数组元素对象,并写入文件,程序退出时,关闭文
- 件;下一次运行时就可以由文件构造对象,恢复前一次做过的工作。*/
- #include<fstream>
- #include<iostream>
- #include<string>
- #include<iomanip>
- using namespace std;
- class student{
- int id ; //学号
- string name; // 姓名
- char sex; // 性别
- int age; // 年龄
- string address; //家庭地址
- float eng, phy, math, electron; //英语,物理,数学和电子学成绩
- public:
- student(int=0,string="#",char='#',int=0,string="#",float=0,float=0,float=0,float=0);
- void Bdatatofile(fstream & dest); //数据写入文件流类
- void Bdatafromfile(fstream & sour); //由文件流类读出数据
- bool operator<=(student &ele){return id<=ele.id;}
- bool operator==(student &ele){return id==ele.id;}
- friend ostream&operator<<(ostream&dest,student&st); //重载插入运算符
- friend istream&operator>>(istream&sour,student&st); //重载提取运算符
- };
- student::student(int i,string n,char s,int a,string add,float en,float ph,float ma,float ele){
- id=i;
- name=n;
- sex=s;
- age=a;
- address=add;
- eng=en; phy=ph; math=ma; electron=ele;
- }
- void student::Bdatatofile(fstream & dest){ //流类作为形式参数必须是引用
- dest.write((char*)&id,sizeof(int));
- dest.write(name.c_str(),20);//由string类的c_str()函数转为char*
- dest.write((char*)&sex,sizeof(char));
- dest.write((char*)&age,sizeof(int));
- dest.write(address.c_str(),20);//由string类的c_str()函数转为char*
- dest.write((char*)&eng,sizeof(float));
- dest.write((char*)&phy,sizeof(float));
- dest.write((char*)&math,sizeof(float));
- dest.write((char*)&electron,sizeof(float));
- }
- void student::Bdatafromfile(fstream & sour){ //流类作为形式参数必须是引用
- char Desc[20];
- sour.read((char*)&id,sizeof(int));
- sour.read(Desc,20);//必须由字符数组过渡
- name=Desc;
- sour.read((char*)&sex,sizeof(char));
- sour.read((char*)&age,sizeof(int));
- sour.read(Desc,20);//必须由字符数组过渡
- address=Desc;
- sour.read((char*)&eng,sizeof(float));
- sour.read((char*)&phy,sizeof(float));
- sour.read((char*)&math,sizeof(float));
- sour.read((char*)&electron,sizeof(float));
- }//由此可见读和写是完全对称的过程,次序决不能错
- ostream&operator<<(ostream&dest,student&st){ //重载插入运算符
- dest<<st.id<<'t'<<st.name<<'t'<<st.sex<<'t'<<st.age<<'t'<<st.address<<'t'
- <<st.eng<<'t'<<st.phy<<'t'<<st.math<<'t'<<st.electron<<endl;
- return dest;
- }
- istream&operator>>(istream&sour,student&st){ //重载提取运算符
- cout<<"请输入学号:"<<endl;
- sour>>st.id;
- cout<<"请输入姓名:"<<endl;
- sour>>st.name;
- cout<<"请输入性别:"<<endl;
- sour>>st.sex;
- cout<<"请输入年龄:"<<endl;
- sour>>st.age;
- cout<<"请输入地址:"<<endl;
- sour>>st.address;
- cout<<"请输入英语、物理、数学、电子各科成绩:"<<endl;
- sour>>st.eng>>st.phy>>st.math>>st.electron;
- return sour;
- }
- template <typename T>class Array{
- T *elements;
- int Subscript; //已用最大下标值
- int maxSize;
- fstream datafile;
- public:
- Array(int=3); //为了便于检验,缺省元素数暂为3
- ~Array();
- bool IsFull() const{return Subscript==maxSize-1;}
- void renews(); //内存扩大一倍
- void show(){
- cout<<"已用最大下标值"<<Subscript<<'t'<<"可用元素数"<<maxSize<<endl;
- }
- void ordinsert(T&); //输入时以学号为关键字排序
- friend ostream&operator<<(ostream&dest,Array&ar); //重载插入运算符
- };
- template <typename T> Array<T>::Array(int maxs){
- maxSize=maxs;
- Subscript=-1; //私有数据不容许直接赋初值,必须在构造函数中赋初值
- T temp;
- elements=new T[maxSize];
- datafile.open("mydatafile.dat",ios::binary|ios::in); //如文件不存在,打开失败
- if(!datafile==0){
- while(!datafile.eof()){
- temp.Bdatafromfile(datafile);
- if(datafile.eof()==0){ //读到无数据可读后,即读入不成功,eofbit为1
- ordinsert(temp); //即使原文件未排序,退出时按排好序的重存
- }
- }
- datafile.close(); //必须放此处,打开成功才能关闭
- }
- datafile.clear(0); //前面曾经读到文件结束或文件打开失败,流无法恢复
- }
- template <typename T> Array<T>::~Array(){
- int i;
- datafile.open("mydatafile.dat",ios::binary|ios::out);
- for(i=0;i<=Subscript;i++) elements[i].Bdatatofile(datafile);
- datafile.close();
- delete[]elements;
- }
- template <typename T> void Array<T>::renews(){
- int i;
- T *temp=elements;
- maxSize*=2;
- elements=new T[maxSize];
- for(i=0;i<=Subscript;i++) elements[i]=temp[i];
- delete[]temp;
- }
- template <typename T> void Array<T>::ordinsert(T & elem){ //输入时以学号为关键字排序
- int i,j;
- if(IsFull()) renews();
- for(i=0;i<=Subscript;i++) if(elem<=elements[i]) break;
- if(!(elem==elements[i])){
- for(j=Subscript;j>=i;j--) elements[j+1]=elements[j];
- Subscript++;
- }
- elements[i]=elem;
- show();
- }
- template <typename T> ostream&operator<<(ostream&dest,Array<T>&ar){
- int i;
- for(i=0;i<=ar.Subscript;i++) cout<<ar.elements[i];
- return dest;
- }
- int main(){
- Array<student> mylist;
- student temp;
- char ch;
- cout<<"是否输入新学生信息?Y or N"<<endl;
- cin>>ch;
- while(ch=='Y'||ch=='y'){
- cin.get();//吸收回车
- cin>>temp;
- mylist.ordinsert(temp);
- cout<<"是否继续输入?Y or N"<<endl;
- cin>>ch;
- }
- cout<<mylist;
- return 0;
- }