ep9_12.cpp
上传用户:wxcui2006
上传日期:2022-07-12
资源大小:1274k
文件大小:5k
源码类别:

书籍源码

开发平台:

Visual C++

  1. /*9.12 将学校里的学生,定义为一个学生数组类,数组对象动态建立,初始为3个元素,不够用时扩充
  2. 一倍。要求放在构造函数中用二进制数据文件建立数组元素对象,在析构函数中保存数据和关闭文件。
  3. 第一次运行时,建立空的数据文件,由键盘输入建立数组元素对象,并写入文件,程序退出时,关闭文
  4. 件;下一次运行时就可以由文件构造对象,恢复前一次做过的工作。*/
  5. #include<fstream>
  6. #include<iostream>
  7. #include<string>
  8. #include<iomanip>
  9. using namespace std;
  10. class  student{
  11. int   id ;           //学号
  12. string name;         // 姓名
  13. char  sex;          // 性别
  14. int   age;          // 年龄
  15. string  address;      //家庭地址
  16. float  eng, phy, math, electron;     //英语,物理,数学和电子学成绩
  17. public:
  18. student(int=0,string="#",char='#',int=0,string="#",float=0,float=0,float=0,float=0);
  19. void Bdatatofile(fstream & dest);    //数据写入文件流类
  20. void Bdatafromfile(fstream & sour);  //由文件流类读出数据
  21. bool operator<=(student &ele){return id<=ele.id;}
  22. bool operator==(student &ele){return id==ele.id;}
  23. friend ostream&operator<<(ostream&dest,student&st);   //重载插入运算符
  24. friend istream&operator>>(istream&sour,student&st);   //重载提取运算符
  25. };
  26. student::student(int i,string n,char s,int a,string add,float en,float ph,float ma,float ele){
  27. id=i;
  28. name=n;
  29. sex=s;
  30. age=a;
  31. address=add;
  32. eng=en; phy=ph; math=ma; electron=ele;
  33. }
  34. void student::Bdatatofile(fstream & dest){   //流类作为形式参数必须是引用
  35. dest.write((char*)&id,sizeof(int));
  36. dest.write(name.c_str(),20);//由string类的c_str()函数转为char*
  37. dest.write((char*)&sex,sizeof(char));
  38. dest.write((char*)&age,sizeof(int));
  39. dest.write(address.c_str(),20);//由string类的c_str()函数转为char*
  40. dest.write((char*)&eng,sizeof(float));
  41. dest.write((char*)&phy,sizeof(float));
  42. dest.write((char*)&math,sizeof(float));
  43. dest.write((char*)&electron,sizeof(float));
  44. }
  45. void student::Bdatafromfile(fstream & sour){   //流类作为形式参数必须是引用
  46. char Desc[20];
  47. sour.read((char*)&id,sizeof(int));
  48. sour.read(Desc,20);//必须由字符数组过渡
  49. name=Desc;
  50. sour.read((char*)&sex,sizeof(char));
  51. sour.read((char*)&age,sizeof(int));
  52. sour.read(Desc,20);//必须由字符数组过渡
  53. address=Desc;
  54. sour.read((char*)&eng,sizeof(float));
  55. sour.read((char*)&phy,sizeof(float));
  56. sour.read((char*)&math,sizeof(float));
  57. sour.read((char*)&electron,sizeof(float));
  58. }//由此可见读和写是完全对称的过程,次序决不能错
  59. ostream&operator<<(ostream&dest,student&st){   //重载插入运算符
  60. dest<<st.id<<'t'<<st.name<<'t'<<st.sex<<'t'<<st.age<<'t'<<st.address<<'t'
  61. <<st.eng<<'t'<<st.phy<<'t'<<st.math<<'t'<<st.electron<<endl;
  62. return dest;
  63. }
  64. istream&operator>>(istream&sour,student&st){   //重载提取运算符
  65. cout<<"请输入学号:"<<endl;
  66. sour>>st.id;
  67. cout<<"请输入姓名:"<<endl;
  68. sour>>st.name;
  69. cout<<"请输入性别:"<<endl;
  70. sour>>st.sex;
  71. cout<<"请输入年龄:"<<endl;
  72. sour>>st.age;
  73. cout<<"请输入地址:"<<endl;
  74. sour>>st.address;
  75. cout<<"请输入英语、物理、数学、电子各科成绩:"<<endl;
  76. sour>>st.eng>>st.phy>>st.math>>st.electron;
  77. return sour;
  78. }
  79. template <typename T>class Array{
  80. T *elements;
  81. int Subscript;           //已用最大下标值
  82. int maxSize;
  83. fstream datafile;
  84. public:
  85. Array(int=3);           //为了便于检验,缺省元素数暂为3
  86. ~Array();
  87. bool IsFull() const{return Subscript==maxSize-1;}
  88. void renews();         //内存扩大一倍
  89. void show(){
  90. cout<<"已用最大下标值"<<Subscript<<'t'<<"可用元素数"<<maxSize<<endl;
  91. }
  92. void ordinsert(T&);    //输入时以学号为关键字排序
  93. friend ostream&operator<<(ostream&dest,Array&ar);    //重载插入运算符
  94. };
  95. template <typename T> Array<T>::Array(int maxs){
  96. maxSize=maxs;
  97. Subscript=-1;  //私有数据不容许直接赋初值,必须在构造函数中赋初值
  98. T temp;
  99. elements=new T[maxSize];
  100. datafile.open("mydatafile.dat",ios::binary|ios::in);  //如文件不存在,打开失败
  101. if(!datafile==0){
  102. while(!datafile.eof()){
  103. temp.Bdatafromfile(datafile);
  104. if(datafile.eof()==0){   //读到无数据可读后,即读入不成功,eofbit为1
  105. ordinsert(temp);   //即使原文件未排序,退出时按排好序的重存
  106. }
  107. }
  108. datafile.close();            //必须放此处,打开成功才能关闭
  109. }
  110. datafile.clear(0);    //前面曾经读到文件结束或文件打开失败,流无法恢复
  111. }
  112. template <typename T> Array<T>::~Array(){
  113. int i;
  114. datafile.open("mydatafile.dat",ios::binary|ios::out);
  115. for(i=0;i<=Subscript;i++) elements[i].Bdatatofile(datafile);
  116. datafile.close();
  117. delete[]elements;
  118. }
  119. template <typename T> void Array<T>::renews(){
  120. int i;
  121. T *temp=elements;
  122. maxSize*=2;
  123. elements=new T[maxSize];
  124. for(i=0;i<=Subscript;i++) elements[i]=temp[i];
  125. delete[]temp;
  126. }
  127. template <typename T> void Array<T>::ordinsert(T & elem){ //输入时以学号为关键字排序
  128. int i,j;
  129. if(IsFull()) renews();
  130. for(i=0;i<=Subscript;i++) if(elem<=elements[i]) break;
  131. if(!(elem==elements[i])){
  132. for(j=Subscript;j>=i;j--) elements[j+1]=elements[j];
  133. Subscript++;
  134. }
  135. elements[i]=elem;
  136. show();
  137. }
  138. template <typename T> ostream&operator<<(ostream&dest,Array<T>&ar){
  139. int i;
  140. for(i=0;i<=ar.Subscript;i++) cout<<ar.elements[i];
  141. return dest;
  142. }
  143. int main(){
  144. Array<student> mylist;
  145. student temp;
  146. char ch;
  147. cout<<"是否输入新学生信息?Y or N"<<endl;
  148. cin>>ch;
  149. while(ch=='Y'||ch=='y'){
  150. cin.get();//吸收回车
  151. cin>>temp;
  152. mylist.ordinsert(temp);
  153. cout<<"是否继续输入?Y or N"<<endl;
  154. cin>>ch;
  155. }
  156. cout<<mylist;
  157. return 0;
  158. }