1.题目
现有学生成绩信息,内容如下
姓名 学号 语文 数学 英语
张明明 01 67 78 82
李成友 02 78 91 88
张辉灿 03 68 82 56
王露 04 56 45 77
陈东明 05 67 38 47
… … … … …
请编写一实现学生信息管理系统,用C++及类和对象来进行抽象、封装与实现,
注意学生的成绩需要用链表来实现,并且链表也需要实现封装,包含以下功能(要求):
- 信息维护:
a)学生信息数据要以文件的形式保存,能实现学生信息数据的维护
b)此模块包括子模块有:增加学生信息、删除学生信息、修改学生信息
c)在程序中能够以链表的形式从文件中读入数据 - 信息查询:
查询时可实现按姓名查询、按学号查询 - 成绩统计:
a)输入任意的一个课程名(如数学)给出该门课程的成绩的分段统计(以10分为一个
成绩段,如90-100,80-89,70-79,60-69,小于60),给出在此分数段的学生数目
b)根据指定的课程名求该门课所有学生的平均成绩
c)给出每个学生的平均成绩 - 排序:
能对指定的任意课程名,按成绩升序或降序排列学生数据并显示排序结果 - 采用文本菜单界面
2.总体分析
该代码包含在三个文件,一个为主函数文件work4main.cpp,一个为要存放到文件work4.txt当中的学生信息的类和存放所有操作函数的类的文件work4class.h,一个为存放各个操作函数的文件work4function.cpp。其中文件work4class.h中的学生信息结点的类通过在存放操作函数的类的private中定义该类型的指针来把这两个类联系起来,这样就可以把这存放函数的类看作是存放学生信息的类的链表了,这为以后的函数操作提供了很多便利。
存放函数的类中的定义构造函数和析构函数,因为每个类里面的函数通过对象调用时也会调用这两个操作函数,所以可以把打开文件的操作和保存文件的操作分别放在这两个函数中,这样就要求在关闭文件时要通过正常渠道退出才会保存文件,否则就不会保存。然后就是各个函数的具体代码了,然后通过主函数进行相关调用相关功能函数。
3.详细设计
首先看一下文件work4class.h,代码前面要define这个文件,把它定义成一个头文件类型。然后里面定义两个类,其中一个主要是包含学生信息的,这部分信息是要写进文件里面的,还有一个指向下一个类的指针Student *next,接着还有ifstream类型的引用调用参数,名为in,用于将信息从文件输入结点;另一个类是声明各个操作函数,还有定义信息结点的头和尾,最后还有创建文件输入和输出流,类如下所示:
//学生信息结点
class Student{
public:
char student_name[20];
char student_ID[10];
int chinese_score;
int math_score;
int english_score;
int average_score;
Student *next;
void input();
void readfile(ifstream &in);
};
//学生信息结点链表
class Student_information
{
public:
Student_information();
~Student_information();
void show_menu();//显示菜单
void add(); //增加
void del(); //删除
void display(); //显示
void find(); //查询
void modify(); //修改
void save(); //保存
void copy(Student *p1,Student *p2);//交换节点
void sort(); //排序
void count(); //统计
void clean(); //清除
private:
//Student_information类可以看作是以Student类为结点的链表
Student *head;//链表头
Student *end; //链表尾
ifstream in;
ofstream out;
};
接着看主函数部分:主函数部分相对简单,开头要用#include "work4class.h"把前面定义的类给的文件给包含进来。然后main函数里面主要是通过一个switch语句并用一个对象来调用各个函数,当然了,首先当然要输入指定的指令。然后在switch外面用一个while循环实现多次调用,除非输入0才跳出循环,结束程序,并输出信息至文件work4.txt保存。
接着看一下文件work4function.cpp,也就是操作函数定义部分。首先是一个输入学生信息函数,最后还会根据输入的三科成绩算出平均成绩,这是直接从键盘输入到内存的,还没有保存到文件中,后面的修改和增加信息的都会用到这个函数。接着就是一个将文件读取所有学生信息到结点的函数,直接用文件输出流in来实现。
下面是一个构造函数,先初始化头结点和尾结点,然后就是读一下文件才可以对文件里面的信息用函数进行相应操作。后面会用这部分代码判断文件是否为空:
char ch = in.get();
if(in.eof())
{
cout<<"文件为空!"<<endl;
}
如果文件非空,就执行下面这部分。这段代码是从网上找的,具体的为什么这样我也不是很明白,但是如果不加的话退出程序之后就无法保存文件,在此打开文件是会显示空,所以只能当成模板来使用了。
while(!in.eof())
{
end->readfile(in);
if(end->student_name[0]=='\0')
break;//不加这一句的话程序会把文件最后结束的标记也都出来
end->next = new Student;
end = end->next;
}
后面就是析构函数,首先会调用一个保存的信息至为文件的函数将信息保存,该保存信息函数是单独写的,具体是首先要打开文件,接着是判断内存里面的学生信息是否为空,如果非空那么用文件输入流out将信息写入文件。调用保存函数之后就是析构函数里面的释放指针,就是利用一个while循环里面的delete函数逐个释放掉。接着是增加学生信息结点的函数,首先将尾指针指向输入函数,如果不这样而是直接调用该函数,会报错说该函数没有声明,因为该类的函数无法直接调用另一个关联的类的函数,需要用到指针实现。然后就是为end->next分配一块内存,最后会有一个switch语句判断是否继续输入信息
然后就是修改信息的函数,输入修改信息的学生名字,然后就会逐个匹配信息直到找到所修改的,找到后会调用输入函数可直接对所有信息进行修改。然后就是删除信息的函数,同样的输入想要删除的学生名字,用循环从头开始找直到找到该结点,找到之后把它的指针next赋给上一个结点的的next,然后把该指针delete掉即可。后面是查找部分,输入指定指令按学号或按姓名查询,接着用两个if语句中的一个进行相应查询,比如用到按学号查询的语句,输入学号,用指针逐个进行查找,找到后直接用cout输出即可,并标记flag为1,用这个来判断查询是否成功。
然后就是显示所有学生信息的函数,同样的还是会判断是否为空,然后用循环for(pos;pos!=end;pos=pos->next)逐个输出显示学生信息。紧接着是统计函数,同查找一样,首先显示要统计什么,输入相应指令进行相应的统计,比如输入1统计语文分数的,定义7个变量并初始化用来存放各个分数段的人数以及记录学生总人数以及该科目的总成绩,用来计算平均分,同样的还是for循环一个一个从头到尾判断该分数所属分数段并记录人数以及总分,最后输出显示到屏幕上。
然后是排序部分,套路和上面的基本一样,只是语法部分变了。分成六种排序,就拿语文成绩降序排序来说,借用冒泡排序,逐个进行相邻的结点成绩大小排序,把高的成绩放到前面,途中会交换两个结点的信息,注意是只交换信息并没有交换指针,而交换信息用到的我写的一个拷贝函数,因为数据还有数字,无法直接用strcpy函数,所以只能另写一个了,其他方式的排序也是按照这样进行,基本就是这样。
for(p1;p1!=end;p1=p1->next)//冒泡排序
{
for(p2=p1->next;p2!=end;p2=p2->next)
{
if(p2->chinese_score > p1->chinese_score)
{
Student *ptemp = new Student;
copy(ptemp, p1);//拷贝函数,将p1的拷进ptmp
copy(p1, p2);
copy(p2, ptemp);
}
}
}
为了清除文档方便,写了一个格式化的函数,以清除数据的方式打开文件,然后再关闭文件即可,但最要的是退出程序要调用exit(0),不调用Student_information类的析构函数退出,否则又会把内存的数据写到C++work4.txt文件中,最后一个函数就是一个用cout直接打印出来的菜单界面函数了
最后看主函数部分:主函数部分相对简单,开头要用#include "work4class.h"把前面定义的类给的文件给包含进来。然后main函数里面主要是通过一个switch语句并用一个对象来调用各个操作函数,当然了,首先当然要输入指定的指令。然后在switch外面用一个while循环实现多次调用,除非输入0才跳出循环,结束程序,并输出信息至文件work4.txt保存,整个程序大体就是这样。
4.源码地址
https://github.com/zhuhezhang/student-achievement-management-system
https://gitee.com/zhuhezhang/student-achievement-management-system