📄 ep9_12.cpp
字号:
/*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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -