/*main.cpp*/
**#include "manage_student.h"
#include "Student.h"
#include<iostream>
#include "Math_Student.h"
#include "IT_Student.h"
#include "English_Student.h"
using namespace std;
/*void traverse(Student *head) {
int index = 1; // 用于计数第几个学生
Student *temp = head;
while (temp != NULL) { //同样一直到后面没有地址结束
cout << temp->math;
temp = temp->next;
}
}*/
void menu(Student *head,manage_student Chead) {
int m = 0;
int ID = 0;
int conter = 0;
while (1) {
cout << " ***************请选择您需要的操作:****************" << endl;
cout << " * 1. 增加学生信息 *" << endl;
cout << " * 2. 删除学生信息 *" << endl;
cout << " * 3. 修改学生信息 *" << endl;
cout << " * 4. 按学号ID查询 *" << endl;
cout << " * 5. 查询某位学生的平均分 *" << endl;
cout << " * 6. 某个学生的三科平均成绩 *" << endl;
cout << " * 7. 按公共课平均分从高到低排序 *" << endl;
cout << " * 8. 遍历学生信息 *" << endl;
cout << " * 9. 结束功能并把信息写入文件中 *" << endl;
cout << " * 0. 退出程序 *" << endl;
cout << " ***************************************************" << endl;
rewind(stdin);
cin >> m;
if (m >=0 && m < 10) {
switch (m) {
case 1: Chead.append_student(head); break;
case 2: {cout << "要删除学生信息的学号:";
cin >> ID;
head = Chead.delete_student(head, ID, Chead.getlength(head)); }break;
case 3: {cout << "需要修改学生信息的同学ID:";
cin >> ID;
Chead.change_message(head, ID); }break;
case 4: {cout << "按学号查询 请输入需要查询的同学的ID为:";
cin >> ID;
Chead.search(head, ID); }break;
case 5: {
cout << "请输入您需要查询学生的平均成绩的ID:";
cin >> ID;
Chead.get_average_score(head,Chead.getlength(head),ID );
}break;
case 6: {
cout << "请输入您需要查询学生的平均成绩的ID:";
cin >> ID;
Student *t = head;
while (t != NULL) {
if (t->ID == ID) {
cout << "该同学的公共课平均成绩为:" << t->get_main_average() << endl;
}t = t->next;
}
break;
}
case 7: {
Chead.rank_average_score(head, Chead.getlength(head));
cout << "排序成功!"; break;
}
case 8: {
Student *t = head;
while (t != NULL) {
t->traverse(t);
t=t->next;
}break;
}
case 9: {
Chead.openfile(head, Chead.getlength(head));
cout << "写入文件成功!"; break;
}
case 0: {
Chead.release(head);//结束之前free掉链表
return; }
}
}
else cout << "输入有错误 请输入0-9的整数"; continue;
}
/*manage_student.h*/
#pragma once
#include<iostream>
#include "Student.h"
class manage_student
{
public:
//存入文件 传入头指针和长度
void openfile(Student *head, int len);
//成绩排序 传入头指针和长度
void rank_average_score(Student *head,int len);
//修改信息 指定ID找到学生信息 修改 传入头 和 ID
void change_message(Student *head, int ID);
//增加信息 传入头就可以
void append_student(Student *head);
//删除学生信息 传入头 需要删除学生信息的ID 链表长度
Student * delete_student(Student *head,int ID,int len);
//创建链表
Student * create();
//搜索查询学生信息 根据ID搜索
void search(Student *head, int ID);
//得到链表的长度 传入头 返回链表长度
int getlength(Student *head);
//得到平均分 显示平均分
void get_average_score(Student *head, int len,int ID);
void release(Student *head);
manage_student();
~manage_student();
};
/*manage_student.cpp*/
#include "manage_student.h"
#include "Student.h"
#include<iostream>
#include "Math_Student.h"
#include "IT_Student.h"
#include "English_Student.h"
#include<string.h>
using namespace std;
#include<fstream>
#include<iomanip>
manage_student::manage_student()
{
}
manage_student::~manage_student()
{
}
Student * manage_student:: create() {
int num = 0; //来计数 输入的第几个学生
int temp; //用来输入选择初始化的学生的专业
int len = 0; //表示链表的长度
cin >> len; //也就是初始输入需要添加的学生数目
Student stu;//用来初始化指针
Student *pre = &stu;
Student *c = &stu;
Student *Head = &stu; //最后要返回的头指针
while (num < len) {
cout << "************您需要添加此学生的专业是? 1:数学系 2:英语系 3:计算机系" << endl;
cin >> temp;
if (temp == 1) {
c = new Math_Student; //一定要new一个**********不然会覆盖之前的
if (num == 0) { // 千万不能 Math_Student c 这个错误调了几天!!!!!!
Head = c; // 头指针的地址
Head->next = NULL; //第一个的尾给空
pre = Head; //pre指向 前一个 也就是头
}
if (num) {
pre->next = c; //前一个的尾接到下一个的地址
pre = pre->next; //pre 指向next指针
pre->next = NULL; //next指针指向的 弄为空
}
++num;
continue;
}
else if (temp ==2 ) {
c = new English_Student;
if (num == 0) {
Head = c; // 头指针的地址
Head->next = NULL; //第一个的尾给空
pre = Head; //pre指向 前一个 也就是头
}
if (num) {
pre->next = c; //前一个的尾接到下一个的地址
pre = pre->next; //pre 指向next指针
pre->next = NULL; //next指针指向的 弄为空
}
++num;
continue;
}
else if (temp == 3) {
c = new IT_Student;
if (num == 0) {
Head = c; // 头指针的地址
Head->next = NULL; //第一个的尾给空
pre = Head; //pre指向 前一个 也就是头
}
if (num) {
pre->next = c; //前一个的尾接到下一个的地址
pre = pre->next; //pre 指向next指针
pre->next = NULL; //next指针指向的 弄为空
}
++num;
continue;
}
else {
cout << "输入有误!请重新输入" << endl; continue;
}
}
return Head; //把头指针返回到main里 便于取用
}
int manage_student::getlength(Student * head)
{
int num = 1; //=0 或者 =1 取决于while的判断条件
Student *t=head;
while (t->next != 0) { //当head指向后面没有了 它就是NULL 结束
++num;
t = t->next; //如果head 不是NULL ++num后要把head指针指向最后
}
return num; //返回int长度
}
void manage_student::search(Student *head,int ID) {
Student *t = head; //用*t来遍历
while (t != NULL) { //只要t不是空 就进入
if (t->ID == ID) { //如果匹配到 ID
t->traverse(t); //用基类的指针调用子类的遍历方法
}t = t->next;
}
}
void manage_student::release(Student *head) {
Student *n; //需要一个指针存着下一个地址
while (head != NULL) {
n = head->next; //把n指向下一块要释放的地址
free(head);
head = n; //然后再把head从前一个地址移到下一个地址
}
}
void manage_student::append_student(Student *head) {
Student *c = head; //都用基类的指针来操作
Student *t = head;
int temp;
while (t->next != NULL) {
t = t->next; //把t移动到最后一块链表
}
cout << "************您需要添加此学生的专业是? 1:数学系 2:英语系 3:计算机系" << endl;
cin >> temp;
if (temp == 1) {
c = new Math_Student; //一定要new一个
t->next = c; //前一个的尾接到下一个的地址
t = t->next; //pre 指向next指针
t->next = NULL; //next指针指向的 弄为空
}
else if (temp == 2) {
c = new English_Student; //一定要new一个
t->next = c; //前一个的尾接到下一个的地址
t = t->next; //pre 指向next指针
t->next = NULL; //next指针指向的 弄为空
}
else if (temp == 3) {
c = new IT_Student; //一定要new一个
t->next = c; //前一个的尾接到下一个的地址
t = t->next; //pre 指向next指针
t->next = NULL; //next指针指向的 弄为空
}
else {
cout << "输入有误!请重新输入" << endl;
}
}
Student * manage_student::delete_student(Student *head, int ID,int len)
{
//用*t来遍历
Student *t = head;
Student *temp;//临时指针
for (int i = 0; i < (len - 1); ++i) {
if (i == 0) { //如果就是第一块链表 需要特殊处理 因为头Head会变
if (head->ID == ID) { head = head->next; delete t; return head; } //一定要返回一个新的头Head
if ((t->next)->ID == ID) { //如果是第二块链表匹配
temp = t->next; //把第一块跟第三块连接起来
t->next = (t->next)->next;
delete temp; return head; //delete调 第二块 返回头Head
}
}
if (i != 0) {
if ((t->next)->ID == ID) { //如果遍历的不是第一块了,操作都一样
temp = t->next; //前一块的next
t->next = (t->next)->next; //前后连接
delete temp; return head; //删掉中间
}t = t->next;
}
}cout << "删除成功!" << endl; return head; //返回头指针
}
void manage_student::change_message(Student *head, int ID) {
Student *t = head;
while (t!= NULL) {
if (t->ID == ID) {//ID匹配 进入
// 匹配属于数学系
if (t->get_major() == "Math_Student") {
//在此处修改公共的信息
cout << "*******请输入要修改的学生信息:" << endl;
cout << " ID:" << endl;
cin >> t->ID;
cout << " 姓名:" << endl;
cin >> t->name;
cout << " 年龄:" << endl;
cin >> t->age;
cout << " 数学:" << endl;
cin >> t->math;
cout << " 英语:" << endl;
cin >> t->english;
cout << " 体育:" << endl;
cin >> t->sport;
t->change(); //然后再去子类里面调用change修改特有的成员变量
}
if (t->get_major() == "English_Student") {
cout << "*******请输入要修改的学生信息:" << endl;
cout << " ID:" << endl;
cin >> t->ID;
cout << " 姓名:" << endl;
cin >> t->name;
cout << " 年龄:" << endl;
cin >> t->age;
cout << " 数学:" << endl;
cin >> t->math;
cout << " 英语:" << endl;
cin >> t->english;
cout << " 体育:" << endl;
cin >> t->sport;
t->change();
}
if (t->get_major() == "IT_Student") {
cout << "*******请输入要修改的学生信息:" << endl;
cout << " ID:" << endl;
cin >> t->ID;
cout << " 姓名:" << endl;
cin >> t->name;
cout << " 年龄:" << endl;
cin >> t->age;
cout << " 数学:" << endl;
cin >> t->math;
cout << " 英语:" << endl;
cin >> t->english;
cout << " 体育:" << endl;
cin >> t->sport;
t->change();
}
cout << "信息修改完成!"<<endl; return;
}
t = t->next;
}
cout << "对不起!查无此人,请重新确认学号是否输入正确,谢谢!"<<endl;
}
void manage_student::rank_average_score(Student *head,int len) {
Student *t = head; //用*t来 遍历
Student *pre = head;//把前面的存着 来跟后面的比较
t = t->next; //t往后移动一个
int ID;
char name[20];
float math, english, sport;
for (int i = 0; i < (len - 1); ++i) {
while (t != NULL) {
//如果后面的平均分比前面的平均分高 就进入
if ( t->get_average_score() >pre->get_average_score() ){
strcpy_s(name, t->name); strcpy_s(t->name, pre->name); strcpy_s(pre->name, name);
ID = t->ID; t->ID = pre->ID; pre->ID = ID;
math = t->math; t->math = pre->math; pre->math = math;
sport = t->sport; t->sport = pre->sport; pre->sport = sport;
english = t->english; t->english = pre->english; pre->english = english;
}
t = t->next;
//t每次循环完了之后 就把pre后移一个 t接在pre的后面
}pre = pre->next; t = pre->next;
}
}
void manage_student::openfile(Student *head, int len) {
//同样用t遍历
Student *t = head;
ofstream ofile; //定义输出文件
ofile.open("D:\学生信息"); //作为输出文件打开
//for循环把链表 里面的信息写入文件
for (int i = 0; i < len; ++i) {
//判断系别 因为每个专业的成员不一样
if (t->get_major() == "Math_Student") {
ofile << "录入的各学生的信息如下: " << endl;
ofile << " 基本信息:" << " 学号" << t->ID << " 姓名:" << t->name << " 年龄:" << t->age << " 专业:" << t->get_major() << endl
<< " 公共课成绩:" << " 数学:" << t->math << " 英语:" << t->english << " 体育:" << t->sport << endl
<< " 专业课成绩:" << " 实变函数" << t->get_shi_bian_fun() << " 泛函分析:" << t->get_fan_han_fen_xi() << " 微分几何" << t->get_wei_fen_jihe() << endl;
t = t->next; continue;
}
if (t->get_major() == "English_Student") {
ofile << "录入的各学生的信息如下: " << endl;
ofile << " 基本信息:" << " 学号" << t->ID << " 姓名:" << t->name << " 年龄:" << t->age << " 专业:" << t->get_major() << endl
<< " 公共课成绩:" << " 数学:" << t->math << " 英语:" << t->english << " 体育:" << t->sport << endl
<< " 专业课成绩:" << " 综合英语:" << t->get_zonghe_english() << " 口语英语:" << t->get_spoken_english() << endl;
t = t->next; continue;
}
if (t->get_major() == "IT_Student") {
ofile << "录入的各学生的信息如下: " << endl;
ofile << " 基本信息:" << " 学号" << t->ID << " 姓名:" << t->name << " 年龄:" << t->age << " 专业:" << t->get_major() << endl
<< " 公共课成绩:" << " 数学:" << t->math << " 英语:" << t->english << " 体育:" << t->sport << endl
<< " 专业课成绩:" << " 组成原理:" << t->get_zu_cheng_yuanli() << " 体系结构:" << t->get_ti_xi_jie_gou() << " 汇编语言:" << t->get_hui_bian() << endl;
t = t->next; continue;
}
}
ofile.close();
return ;
}
void manage_student::get_average_score(Student *head, int len,int ID) {
Student *t = head; //用t遍历
for (int i = 0; i < len; ++i) {
if (t->ID == ID) {
//用基类的指针调用子类的函数 返回平均分 输出
cout << "该学生的平均成绩为:" << t->get_average_score() << endl; return;
}
t = t->next;
}
cout << "请确认您输入的ID是否有误" << endl;
}
;
}
void main() {
cout << "欢迎进入学生管理系统!请输入需要添加的学生数: "<<endl;
Student temp; //用来初始化指针
Student *Head=&temp;
Student *t=&temp;
int len;
manage_student Chead;
Head=Chead.create();//把头地址传回来给Head 指向的是第一个类stu
menu(Head, Chead); //调用菜单函数
system("pause");
return;
}