/////////文件,继承,友元,静态数据成员(没用到),容器类,运算符重载,使用虚函数完成动态多态,模板
#include<iostream>//输入输出流,知识点:运算符重载。在iostream头文件中重载运算符“<<”和“>>”本来在C++中是被定义为左位移运算符和右位移运算符的,由于在iostream头文件中对它们进行了重载, 使它们能用作标准类型数据的输入和输出运算符。
#include<fstream>//读写文件
#include<iomanip>//指定输入输出格式
#include<string>
using namespace std;
////////////////////////////////////////////////////////////////
class Basic//基类
{
public:
virtual int input(ifstream &its) =0;//知识点:使用虚函数完成动态多态,c++中的虚函数就是用来解决动态多态问题的。所谓虚函数,就是在基类声明函数是虚拟的,并不是实际存在的函数,然后在派生类中才正式定义此函数。
//虚函数是指一个类中你希望重载的成员函数
//当你用一个基类指针或引用指向一个继承类对象的时候,调用一个虚函数时, 实际调用的是继承类的版本。多态性
virtual void input()=0;
virtual void display(ofstream &its) =0;
virtual void display()=0;
virtual void display_1() {};
friend class College;///知识点:友元类. College类的所有成员函数都是Basic的友元函数,都可以访问Basic中的隐藏信息(私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
protected:
//把这些数放在这, 方便调用
Basic *next; //指针
int number; //学号
char name[40]; //姓名
int dom_number;//宿舍号
double mark; //综合成绩
int credit; //实得学分
};
////////////////////////////////////////////////////////////
class Student: virtual public Basic////知识点:继承,虚拟派生(虚基类的方法,使得在继承间接共同基类时只保留一份成员)
{
public:
int input(ifstream &its) //输入流 运算符重载
{
its>>number;
if(number==-1)
return 0;
else
{
its>>name>>sex>>dom_number>>phone_number;
return 1;
}
}
void input() //输入
{
cout<<"学号: ";
cin>>number;
cout<<" 姓名:";
cin>>name;
cout<<"性别: ";
cin>>sex;
cout<<"宿舍号码: ";
cin>>dom_number;
cout<<"电话号码: ";
cin>>phone_number;
}
void display(ofstream &its)//输出文件流
{
its<<number<<" "<<name<<" "<<sex<<" "<<dom_number<<" "<<phone_number<<endl;
}
void display() //输出
{
cout<<number<<setw(10)<<name<<setw(6)<<sex<<setw(10)<<dom_number<<setw(13)<<phone_number<<endl;
}
private:
char sex[5] ; //性别
char phone_number[20] ;//电话号码
} ;
////////////////////////////////////////////////////////////
class Course:virtual public Basic////知识点:继承
{
public:
int input(ifstream &its) //输入流函数
{
its>>number;
if(number==-1)
return 0;
else
{
its>>chass_number>>chass_name>>chass_mark>>peacetime_mark>>experiment_mark>>txt_mark;
account() ;
return 1;
}
}
void input() //输入函数
{
cout<<"学号=";
cin>>number;
cout<<"课程编号=";
cin>>chass_number;
cout<<"课程名称=";
cin>>chass_name;
cout<<"学分=";
cin>>chass_mark;
cout<<"平时成绩=";
cin>>peacetime_mark;
cout<<"实验成绩=";
cin>>experiment_mark;
cout<<"卷面成绩=";
cin>>txt_mark;
account();
}
void account() //计算综合成绩和实得学分
{
int i;
if(experiment_mark==-1)
mark=peacetime_mark*0.3+txt_mark*0.7;
else
mark=peacetime_mark*0.15+experiment_mark*0.15+txt_mark*0.7;
i=mark/10;
switch(i)
{
case 10: credit=chass_mark;break;
case 9: credit=chass_mark; break;
case 8: credit=chass_mark*0.8; break;
case 7: credit=chass_mark*0.7; break;
case 6: credit=chass_mark*0.6; break;
default:credit=0;break;
}
}
void display(ofstream &its)//输出流函数
{
its<<number<<" "<<chass_number<<" "<<chass_name<<" "<<chass_mark<<" "<<peacetime_mark<<" "<<experiment_mark<<" "<<txt_mark<<endl;
}
void display() //输出函数
{
cout<<number<<setw(10) <<chass_number<<setw(11) <<chass_name<<setw(5) <<chass_mark<<setw(7) <<peacetime_mark<<setw(10) <<experiment_mark<<setw(10)<<txt_mark<<setw(10) <<mark<<setw(10) <<credit<<endl;
}
void display_1()
{
cout<<"课程编号: "<<chass_number<<" "<<"课程名称: "<<chass_name<<" "<<"综合成绩: "<<mark<<" "<<"实得学分: "<<credit<<endl;
}
private:
char chass_number[30] ;//课程编号
char chass_name[30] ;//课程名称
int chass_mark; //学分
int peacetime_mark; //平时成绩
int experiment_mark;//实验成绩
int txt_mark; //卷面成绩
} ;
///////////////////////////////////////////////////////
class College//链表类/
/*
{
c=new Course;
c->input();
b.Build(c);
}*/
{
private://文件
ifstream f;//定义文件输入流对象(读)支持重载的 >> 操作符。
ofstream s;//定义文件输出流对象(写)支持重载的 << 操作符
Basic *head; //定义基类指针作为链表的头指针
int ji; //计算插入的数
int PL; //判断建立怎样的链表
public:
College(int i) //构造函数建立初链, i=0 建立 Student 链表, i=1 建立 Course链表
{
ji=0;
Basic *p;//定义基类指针
int t;
PL=i;
if(PL==0) //根据 PL, 打开相应的文件
{
f.open("A.txt",ios::in) ;//连接文件,指定打开方式为...
head=new Student;//head=&Student; 基类指针指向继承类对象
p=new Student;// 基类指针指向继承类对象
}
else
{
f.open("B.txt",ios::in) ;
head=new Course;
p=new Course;
}
if(!f) //文件异常处理,判断 f 是否打开文件
{
cout<<"错误"<<endl;
abort();
}
t=head->input(f);
head->next=p;
p->next=NULL;
for(;;) //读入文件数据, 并将数据插入链表中
{
if(i==0)
p=new Student;
else
p=new Course;
t=p->input(f) ;
if(t==0)
break;
head=Build(p);
}
f.close() ;//关闭文件
}
~College()
{
save();
}
Basic *Build(Basic *p)//插入函数, 将 p 有序的插入链表中
{
Basic *p1=head,*p2=head;
int i;
for(i=0;p1->next!=NULL; i++)
{
if(i==0&&p->number<p1->number) //处理头链
{
p->next=p1;
head=p;
ji++;
break;
}
else if(p->number<p1->number) //处理中间
{
p2->next=p;
p->next=p1;
ji++;
break;
}
else if(i==ji) //处理尾
{
p2=p1;
p1=p1->next;
p2->next=p;
p->next=p1;
ji++;
break;
}
p2=p1;
p1=p1->next;
}
return head;
}
void display() //输出链表信息
{
Basic *a=head;
for(;a->next!=NULL;a=a->next)
a->display();
}
void find_number() //查找学号(student)
{
int i;
Basic *h=head;
cout<<"请输入你想找的学号: ";
cin>>i;
for(;h->next!=NULL; h=h->next)
{
if(h->number==i)
{
h->display() ;
break;
}
}
}
void find_name() //查找姓名(student)
{
char i[40];
Basic *h=head;
cout<<"请输入你想找的姓名: ";
cin>>i;
for(;h->next!=NULL; h=h->next)
{
if(strcmp(h->name,i)==0)
{
h->display() ;
break;
}
}
}
void find_dom_number()//查找宿舍号码(student)
{
int i;
Basic *h=head;
cout<<"请输入你想找的宿舍号码:";
cin>>i;
for(;h->next!=NULL; h=h->next)
if(h->dom_number==i)
h->display() ;
}
Basic *get_head()
{
return head;
}
void find(Basic *a) //输入一个学号时, 查询出此生的所有课程情况(Course)
{
int i;
Basic *h=head;
cout<<"请输入你想查的学号: ";
cin>>i;
for(;a->next!=NULL; a=a->next)
{
if(a->number==i)
{
cout<<"学 号: "<<i<<" ";
cout<<"姓 名: "<<a->name<<endl;
break;
}
}
for(;h->next!=NULL; h=h->next)
if(h->number==i)h->display_1() ;
}
void Delete(int j) //删除, j 表示学号
{
Basic *p1=head, *p2=head;
int i=0;
for(;p1->next!=NULL; )
{
if(i==0&&p1->number==j) //处理头
{
head=p1->next;
i=-1;//保证下次还可以删除头链
}
else if(p1->number==j)//处理尾
{
p2->next=p1->next;
}
p2=p1;
p1=p1->next;
i++;
}
}
void delete_student(College &b)//当在 A. TXT 中删除一个学生时,自动地在B. TXT 中删除此人所有信息(student)
{
int i;
cout<<"请输入你想删除的学生的学号: ";
cin>>i;
Delete(i) ;
b. Delete(i) ;
}
void taxis_mark() //综合成绩排序(Course)
{
Basic *a=head;
Basic *m[90] , *t;
int i, j, k, b;
cout<<"升序-1 降序-2"<<endl;
cin>>b;
if(b==1) //升序
{
for(i=0;a->next!=NULL;i++)
{
m[i]=a;
a=a->next;
}
for(j=0;j<i; j++)
for(k=j;k<i; k++)
{
if(m[j] ->mark>m[k] ->mark)
{
t=m[j] ;
m[j] =m[k] ;
m[k] =t;
}
}
cout<<"按综合成绩升序排序为"<<endl;
for(j=0;j<i; j++)
m[j]->display() ;
}
else if(b==2) //降序
{
for(i=0;a->next!=NULL;i++)
{
m[i] =a;
a=a->next;
}
for(j=0;j<i; j++)
for(k=j;k<i; k++)
{
if(m[j]->mark<m[k]->mark)
{
t=m[j] ;
m[j] =m[k] ;
m[k] =t;
}
}
cout<<"按综合成绩降序排序为"<<endl;
for(j=0;j<i; j++)
m[j]->display() ;
}
}
void taxis_credit() //学分排序(Course)
{
Basic *a=head;
Basic *m[90] , *t;
int i, j, k, b;
cout<<"升序-1 降序-2"<<endl;
cin>>b;
if(b==1) //升序
{
for(i=0;a->next!=NULL;i++)
{
m[i]=a;
a=a->next;
}
for(j=0;j<i; j++)
for(k=j;k<i; k++)
{
if(m[j]->credit>m[k]->credit)
{
t=m[j] ;
m[j]=m[k] ;
m[k]=t;
}
}
cout<<"按学分升序排序为"<<endl;
for(j=0;j<i; j++)
m[j]->display() ;
}
else if(b==2) //降序
{
for(i=0;a->next!=NULL;i++)
{
m[i]=a;
a=a->next;
}
for(j=0;j<i; j++)
for(k=j;k<i; k++)
{
if(m[j] ->credit<m[k]->credit)
{
t=m[j] ;
m[j]=m[k] ;
m[k]=t;
}
}
cout<<"按学分降序排序为"<<endl;
for(j=0;j<i; j++)
m[j]->display();
}
}
void save() //保存函数
{
Basic *h=head;
int i=-1;
if(PL==0)
s.open("A.txt",ios::out) ;
else if(PL==1)
s.open("B.txt",ios::out) ;
for(;h->next!=NULL;h=h->next)
h->display(s);
s<<i<<endl;
s.close();
}
};
//////////////////////////////////////////////////
int main()
{
Course *c;
College a(0), b(1);
int k[10];
int i;
to:
cout<<"*****************************************\n"<<endl;
cout<<"* 欢迎使用高校学生成绩管理系统1.0 *\n"<<endl;
cout<<"*****************************************\n"<<endl;
cout<<"* 请选择功能列表 *\n"<<endl;
cout<<"* 1.数据录入功能 *\n"<<endl;
cout<<"* 2.查询功能 *\n"<<endl;
cout<<"* 3.删除功能 *\n"<<endl;
cout<<"* 4.排序功能 *\n"<<endl;
cout<<"* 5.输出并结束 *\n"<<endl;
cout<<"*****************************************\n"<<endl;
cout<<"请输入选项"<<endl;
cin>>i;
if(i==1)
{
c=new Course;
c->input();
b.Build(c);
}
else if(i==2)
{
cout<<"1-学生基本情况查询 2-成绩查询"<<endl;
cin>>k[0];
if(k[0]==1)
{
cout<<"1-学号查询 2-姓名查询 3-宿舍号码查询"<<endl;
cin>>k[1] ;
if(k[1] ==1)
a.find_number();
else if(k[1] ==2)
a.find_name();
else if(k[1] ==3)
a.find_dom_number() ;
goto to;
}
else if(k[0] ==2)
b.find(a. get_head() ) ;
goto to;
}
else if(i==3)
{
a.delete_student(b) ;
goto to;
}
else if(i==4)
{
cout<<"1-综合成绩排序 2-实得学分排序"<<endl;
cin>>k[2] ;
if(k[2] ==2)
b.taxis_credit();
else if(k[2]==1)
b.taxis_mark() ;
goto to;
}
else if(i==5)
{
cout<<"学号 姓名 性别 宿舍号码 电话号码"<<endl;
a.display() ;
cout<<endl;
cout<<"学号 课程编号 课程名称 学分 平时成绩 实验成绩 卷面成绩 综合成绩 实得学分"<<endl;
b.display() ;
goto to;
}
return 0;
}