一、学生成绩管理系统
该系统用于管理学生的课程成绩,要求实现以下功能:
- 计算每位同学的平均分,对所有同学的成绩按平均分排序,给出名次;
- 计算各课程分数段(90-100、80-89、60-79、60以下)的人数。
数据至少有10个学生的原始数据。原始数据如下:
学号 姓名 C程序设计 高等数学 英语 线性代数
1 王.. 80 80 80 80
2 张.. 90 90 90 90
......
最后输出结果如下:
学号 姓名 C程序设计 高等数学 英语 线性代数 平均分 名次
1 王.. 80 80 80 80 80 2
2 张.. 90 90 90 90 90 1
各科平均分 85 85 85 85 85
90-100 1 1 1 1 1
80-89 1 1 1 1 1
60-69 0 0 0 0 0
<60 0 0 0 0 0
二、内容及要求
1、主函数是一个功能选择菜单,其它各功能都用各自的函数实现;
2、所有数据文件形式存储,至少提供10组原始数据,在程序执行前,通过文件导入,程序执行完毕后,再将新的数据存入文件(避免在程序执行过程中反复对文件进行读写);
3、多组数据的存储可用结构体数组,用链表实现可加分;
4、可以对数据可以进行增、删、改的编辑操作,增加时,系统监测所添加信息是否存在,如果存在,会提示已经存在,是否修改;删除时,同样要求再次确定;
5、如涉及到排序、查找操作,使用多种算法如选择排序、冒泡排序、折半查找等可加分;
6、对于程序的输入,要有验证功能,如命令菜单只有5项,输入6将提示输入错误,请重新输入,再如需要输入学号,如果输入中文字符将提示输入错误;
7、在基本功能的基础上,如有创新功能可加分。
三、算法和数据结构设计
程序的基本框架是构建了两个类
(1)学生成绩管理系统类
属性:
○1可指向学生类的对象的指针
○2学生总人数行为:
○1读文件并判断文件是否为未创建或者数据为空
○2读出文件中有多少人
○3展示从文件中读出的数据
○4将用户输入的数据保存到文件中
○5将学生按照成绩进行排名
○6求出各门科目的平均分
○7求出各门科各个分数段的人数
○8添加学生
○9查找学生
○10修改学生
○11删除学生
○12展示学生成绩管理系统的菜单
○13退出学生成绩管理系统)(2)学生类
属性:
○1学号
○2姓名
○3C语言成绩
○4高数成绩
○5英语成绩
○6线性代数成绩
○ 7平均分
○8排名行为:
○1展示自己的信息
以下为程序基本框架和流程图
四、具体代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<fstream>
using namespace std;
class student;
class student_manager
{
public:
student* p;//对象数组指针
student_manager();
~student_manager();
int number;//记录学生总人数
bool read_file(); //读文件,如果文件存在并有数据返回true
int get_filenumber();//读出文件中有多少人
void save_file();//将用户输入的学生信息进行保存
void raw_data();//展示学生的原始数据(从文件中读入的或是用户输入的)
void sort();//将学生按照成绩进行排序
void average();//求出各门科目的平均分
void score_segment();//求各门科及其各个分数区间的人数
void add_student();//添加学生信息
void find_student();//查找学生
void change_student();//修改学生信息
void delete_student();//删除学生
void show_menu();//展示学生成绩管理系统的菜单
void exit_system();//退出系统
};
class student
{
//声明为友元类使其可以访问student类的私有属性
friend bool student_manager::read_file();
friend void student_manager::save_file();
friend void student_manager::raw_data();
friend void student_manager::sort();
friend void student_manager::average();
friend void student_manager::score_segment();
friend void student_manager::add_student();
friend void student_manager::find_student();
friend void student_manager::change_student();
friend void student_manager::delete_student();
public:
student() {}
student(int number, string name, double c_score, double math_score, double english_score, double algebra_score)
{
this->number = number;
this->name = name;
this->c_score = c_score;
this->math_score = math_score;
this->english_score = english_score;
this->algebra_score = algebra_score;
this->average = (c_score + math_score + english_score + algebra_score) / 4.0;
this->ranking = 0;
//存放到数组里面方便后面用
this->urr[0] = this->c_score;
this->urr[1] = this->math_score;
this->urr[2] = this->english_score;
this->urr[3] = this->algebra_score;
this->urr[4] = this->average;
}
void show_information()
{
cout << number << '\t' << name << '\t' << c_score << '\t' << math_score << '\t' << english_score << '\t' << algebra_score << '\t' << average << '\t' << ranking << endl;
}
private:
int number; //学号
string name;//姓名
double c_score; //C语言成绩
double math_score; //高数成绩
double english_score;//英语成绩
double algebra_score;//线性代数成绩
double average; //各门科目的总平均分
double urr[5]; //将四门科目和平均分汇总存放在一起,方便统计
int ranking; //在班里的排名
};
bool student_manager::read_file()//判断文件是否纯在以及里面是否有数据
{
ifstream ifs;
ifs.open("学生成绩管理系统.txt", ios::in);
if (!ifs.is_open())//判断文件是否存在
{
cout << "文件不存在,请输入学生数据!" << endl;
ofstream ofs;
ofs.open("学生成绩管理系统.txt", ios::out);
ifs.close();
return false;
}
char ch;
ifs >> ch;
if (ifs.eof())
{
cout << "文件存在但是数据为空,请输入学生数据!" << endl;
ifs.close();
return false;
}
ifs.seekg(0, ios::beg);//将文件指针重新定位到开头
return true;
}
int student_manager::get_filenumber()//读出文件中一共有几名学生
{
int num=0;
ifstream ifs;
ifs.open("学生成绩管理系统.txt",ios::in);
int number;
string name;
double c_score;
double math_score;
double english_score;
double algebra_score;
while (ifs >> number >> name >> c_score >> math_score >> english_score >> algebra_score)
{
num++;
}
return num;
}
void student_manager::save_file()//将用户输入的学生信息保存到文件里面
{
ofstream ofs;
ofs.open("学生成绩管理系统.txt", ios::out);
for (int i = 0; i < this->number; i++)
{
ofs << p[i].number << '\t' << p[i].name << '\t' << p[i].c_score << '\t' << p[i].math_score << '\t' << p[i].english_score << '\t' << p[i].algebra_score << endl;
}
ofs.close();
}
student_manager::student_manager()
{
if (read_file() != false)//如果文件里面有数据就从文件里面读
{
ifstream ifs;
ifs.open("学生成绩管理系统.txt", ios::in);
this->number = get_filenumber();
this->p = new student[this->number];//动态开辟一段空间,并用p指向他
int number;
string name;
double c_score;
double math_score;
double english_score;
double algebra_score;
int i = 0;
while (ifs >> number >> name >> c_score >> math_score >> english_score >> algebra_score)
{
p[i] = student(number, name, c_score, math_score, english_score, algebra_score);
i++;
}
ifs.close();
}
else //如果文件里面没有数据就让用户输入数据
{
int number;
string name;
double c_score;
double math_score;
double english_score;
double algebra_score;
cout << "请输入您要输入的学生数目:";
cin >> this->number;
this->p = new student[this->number];//动态开辟
for (int i = 0; i <this->number; i++)
{
cout << "请输入第" << i + 1 << "学生的信息" << endl;
cout << "学号 姓名 C程序设计 高等数学 英语 线性代数 " << endl;
cin >> number >> name >> c_score >> math_score >> english_score >> algebra_score;
p[i] = student(number, name, c_score, math_score, english_score, algebra_score);
}
save_file();//用户输完后把数据存到文件里面
}
}
student_manager::~student_manager()
{
if (this->p != NULL)//手动释放开辟在堆区的空间
{
delete p;//归还内存
p = NULL;//将指针指向空
this->number = 0;
}
}
void student_manager::raw_data()
{
cout << "学号 姓名 C程序设计 高等数学 英语 线性代数 " << endl;
for (int i = 0; i < this->number; i++)
{
cout << p[i].number << '\t' << p[i].name << '\t' << p[i].c_score << '\t' << p[i].math_score << '\t' << p[i].english_score << '\t' << p[i].algebra_score << endl;
}
}
void student_manager::sort()
{
for (int i = 0; i < this->number - 1; i++)//冒泡排序
{
for (int j = 0; j < this->number - 1 - i; j++)
{
if (p[j].average< p[j + 1].average)
{
student temp;
temp = p[j];//交换
p[j] = p[j + 1];
p[j + 1] = temp;
}
}
}
for (int i = 0; i < this->number; i++)
{
p[i].ranking = i+1;
}
for (int i =0; i <this->number-1; i++)//用于处理平均分相同的情况
{
if (p[i].average == p[i + 1].average)
{
p[i+1].ranking = p[i].ranking;//并列排名
}
}
cout << "学号 姓名 C程序设计 高等数学 英语 线性代数 平均分 名次 " << endl;
for (int i = 0; i < this->number; i++)
{
p[i].show_information();
}
}
void student_manager::average()
{
double c_score = 0;
double math_score = 0;
double english_score = 0;
double algebra_score = 0;
double average = 0;
for (int i = 0; i < this->number; i++)
{
c_score += p[i].c_score;
math_score += p[i].math_score;
english_score += p[i].english_score;
algebra_score += p[i].algebra_score;
average += p[i].average;
}
c_score /= (double)this->number;
math_score /= (double)this->number;
english_score /= (double)this->number;
algebra_score /= (double)this->number;
average /= (double)this->number;
cout << " C程序设计 高等数学 英语 线性代数 平均分 " << endl;
cout << "各科平均分 " << c_score << '\t' << math_score << '\t' << english_score << '\t' << algebra_score << '\t' << average << endl;
}
void student_manager::score_segment()
{
int arr[4][5] = { 0 };
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < this->number; j++)
{
if (p[j].urr[i] >= 90 && p[j].urr[i] <= 100)
{
arr[0][i]++;
}
if (p[j].urr[i] >= 80 && p[j].urr[i] <= 90)
{
arr[1][i]++;
}
if (p[j].urr[i] >= 60 && p[j].urr[i] <= 80)
{
arr[2][i]++;
}
if (p[j].urr[i] >= 0 && p[j].urr[i] <= 60)
{
arr[3][i]++;
}
}
}
cout << " 90-100 ";
for (int i = 0; i < 5; i++)
{
cout << arr[0][i] << '\t';
}
cout << endl;
cout << " 80-89 ";
for (int i = 0; i < 5; i++)
{
cout << arr[1][i] << '\t';
}
cout << endl;
cout << " 60-69 ";
for (int i = 0; i < 5; i++)
{
cout << arr[2][i] << '\t';
}
cout << endl;
cout << " 60以下 ";
for (int i = 0; i < 5; i++)
{
cout << arr[3][i] << '\t';
}
cout << endl;
}
void student_manager::add_student()
{
cout << "请输入您要添加的学生人数:";
int add_number;
cin >> add_number;
int t = this->number + add_number;
student* temp=new student[this->number+add_number];//动态开辟一段新的空间
for (int i = 0; i < this->number; i++)
{
temp[i] = p[i];//将原来的数据拷贝到新的空间下面
}
int number;
string name;
double c_score;
double math_score;
double english_score;
double algebra_score;
for (int i =this->number; i < add_number+this->number; i++)
{
newpoint:
cout << "请输入第你要添加的第" << i - this->number + 1 << "个学生的信息" << endl;
cout << "学号 姓名 C程序设计 高等数学 英语 线性代数 " << endl;
cin >> number >> name >> c_score >> math_score >> english_score >> algebra_score;
for (int i = 0; i < this->number; i++)
{
if (number == p[i].number)
{
cout << "输入有误,请勿重新输入学号" << endl;//如果用户输入的学号已经存在,跳转到前面让他重新输入
goto newpoint;
}
}
temp[i] = student(number, name, c_score, math_score, english_score, algebra_score);
}
this->p = temp;//p指针指向新的空间
this->number = t;//更新学生的人数
save_file();
cout << "添加学生成功!" << endl;
}
void student_manager::find_student()
{
cout << "请输入您要查找的学生的学号:";
int num;
cin >> num;
for (int i = 0; i < this->number; i++)
{
if (this->p[i].number == num)
{
cout << "查找学生成功!该学生的信息如下" << endl;
cout << "学号 姓名 C程序设计 高等数学 英语 线性代数 平均分 名次 " << endl;
this->p[i].show_information();
return;
}
}
cout << "查找失败,查无此人!"<<endl;
}
void student_manager::change_student()
{
cout << "请输入您要修改信息的学生的学号";
int num;
cin >> num;
int subscript=-1;
for (int i = 0; i < this->number; i++)
{
if (this->p[i].number == num)
{
subscript = i;
break;
}
}
if (subscript == -1)
{
cout << "没有这个人,无法修改其信息" << endl;
return;
}
newpoint1:
cout << "请输入您要修改的学生信息" << endl;
int number;
string name;
double c_score;
double math_score;
double english_score;
double algebra_score;
cout << "学号 姓名 C程序设计 高等数学 英语 线性代数 " << endl;
cin >> number >> name >> c_score >> math_score >> english_score >> algebra_score;
for (int i = 0; i < this->number; i++)
{
if (p[i].number == number)//将该学生的学号改为已经存在的(除非是他自己本来的学号)提示用户重新输入正确的学号
{
if (p[i].number != num)
{
cout << "输入有误,您输入的学生学号已经存在,请重新输入!" << endl;
goto newpoint1;
}
}
}
p[subscript] = student(number, name, c_score, math_score, english_score, algebra_score);
cout << "修改学生信息成功!" << endl;
save_file();
}
void student_manager::delete_student()
{
cout << "请输入您要删除的学生学号:";
int num;
cin >> num;
int subscript = -1;
for (int i = 0; i < this->number; i++)
{
if (this->p[i].number == num)
{
subscript = i;
break;
}
}
if (subscript == -1)
{
cout << "没有这个人,无法删除其信息" << endl;
return;
}
for (int i = subscript; i < this->number - 1; i++)
{
this->p[i] = this->p[i + 1];
}
this->number--;
cout << "删除成功!" << endl;
save_file();
}
void student_manager::show_menu()
{
cout << " _ _____ / /________ ____ ___ ___ " << std::endl;
cout << " | | /| / / _ \\/ / ___/ __ \\/ __ `__ \\/ _ \\" << std::endl;
cout << " | |/ |/ / __/ / /__/ /_/ / / / / / / __/" << std::endl;
cout << " |__/|__/\\___/_/\\___/\\____/_/ /_/ /_/\\___/ " << std::endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 学生成绩管理系统 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "|\\· /\\ ·/\\· /\\ ·[系统功能菜单]· /\\ ·/\\· /\\ ·/|" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 0.展示原始学生信息 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 1.展示学生成绩及排名 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 2.展示各课程分数段人数 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 3.添加学生信息 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 4.查找学生信息 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 5.修改学生信息 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 6.删除学生信息 |" << endl;
cout << "|--------------------------------------------|" << endl;
cout << "| 7.退出系统 |" << endl;
cout << "|--------------------------------------------|" << endl;
}
void student_manager::exit_system()
{
cout << "【退出系统】" << endl;
cout << "欢迎下次使用!" << endl;
exit(0);
}
int main()
{
student_manager A;
while (true)
{
A.show_menu();
int choice;
cout << "请输入您的选择:";
cin >> choice;
switch (choice)
{
case 0: A.raw_data(); break;
case 1: A.sort(); break;
case 2: {
A.average(); A.score_segment(); break;
}
case 3: A.add_student(); break;
case 4: A.find_student(); break;
case 5: A.change_student(); break;
case 6: A.delete_student(); break;
case 7: A.exit_system(); break;
default:cout << "输入有误,请正确输入" << endl; break;
}
system("pause");
system("cls");
}
return 0;
}
五、运行效果
○1当文件不存在
时创建文件,并提示用户录入学生信息,并将录入的信息保存到文件中
○2当文件里面没有数据时让用户录入学生信息,并将录入的信息保存到文件中
○3文件存在且有数据时,将文件里数据读出来,用户可直接根据菜单进行功能体验,不必再输入一遍数据
○4功能0(展示从文件中读的原始数据或用户键入的原始数据)
○5功能1(展示按平均分排序后的学生信息及其排名)
注:考虑有同学平均分相同的情况,如下的小刘和小张,均分均为86,并列排名第4名
○6功能2(展示各个课程的平均分及各个分数段人数)
○7功能3(添加学生)
(1) 要添加学生的学号不是已经存在时
(2) 要添加学生的学号已经存在时,提示用户输入有误,让用户重新输入
检验:可见学生成功添加进去了
○8功能4(查找学生)
(1) 当查找学生学号存在时
(2)当查找的学生不存在时
○9功能5(修改学生信息)
(1)修改后的学号未与已有学生(本身除外)的学号冲突
(2) 修改后的学生学号与已有的学生冲突,提示用户输入错误,让其再次输入
检验:可见大山的信息成功被修改
○10功能6(删除学生)
(1)输入的学号存在
(2)输入的学号不存在
○11功能7(退出系统)
补:当用户的选择错误时提示用户正确输入选择
六、注意事项
有一些细节要注意:
1.当平均成绩相同时注意其排名并列的情况
2.查找学生和删除学生时,如果学生的学号不存在时,要提示用户正确进行输入
3添加学生信息时,如果添加后的学生的学号是已经存在的学号是,提示用户正确输入,并利用goto语句跳转让用户再次输入
4.修改学生信息时,如果修改后的学生的学号与已有的学生学号互相冲突时(除非是要修改学生的原来的学号),提示用户正确输入,并利用goto语句跳转让用户再次输入
综合,要多方面考虑,注意细节