学生成绩系统
要求:
1、 学生信息包括学号、姓名、性别、班级、电话以及各科成绩;
2、 能添加、修改、删除学生的成绩;
3、 能查询成绩;
4、 能计算平均绩点。
Github链接:https://github.com/KrisitVvv/cpplessondesign.git
首先我们需要先构思功能的结构和实现步骤。
根据要求一中,第一反应应该为创建一个类用于储存学生的信息
class person {
private:
char name[10] = { 0 };
char sex[5] = { 0 };
int tel;
char num[15]={0};
};
至于成绩…由于考虑到实际中学生会出现重名的情况,因此成绩的储存以学号为基础。为了成绩类能继承姓名和学号,我们需要把name和num切换到public状态,然后在成绩类中创建课程名称、成绩、学分的数据成员。
class person {
public:
char num[15] = { 0 };
char name[10] = { 0 };
private:
char sex[5] = { 0 };
int tel;
};
class student:public person{
private:
char cname[15] = { 0 };
int score;
float credit;
};
有了类之后,需要将数据输入进类中。
void person::add() {
int choose;
cout << "请输入你的学号:";
cin >> num;
cout << "请输入姓名:";
cin >> name;
lable1:
cout << "请选择性别:" << '\t'<<"1、男\t2、女"<<endl;
cout << "请输入你的选择:";
cin >> choose;
if (choose == 1) {
char temp[4] = "男";
strcpy_s(sex, temp);
}
else if (choose == 2) {
char temp[4] = "女";
strcpy_s(sex, temp);
}
else {
cout << "输入有误,请重新选择!" << endl;
goto lable1;
}
cout << "请输入你的电话:";
cin >> tel;
}
由于我们设计的是成绩管理系统,不能让数据一直在内存中 ,因此我们需要让数据存储到硬盘中。
此处通过对象将数据写入到user.txt文件中,在file对象中,ios::out和ios::app同时使用,如果没有此文件生成一个空文件,并将指针放到文件末尾。
void person::setfile() {
person p;
p.add();
fstream file("user.txt", ios::out | ios::app);
file.write((char*)&p, sizeof(p));
file.close();
cout << "保存成功" << endl;
}
同时,此处声明了两个函数,但是独立在person类外,因此要在person类中声明此函数。
class person {
public:
char num[15] = { 0 };
char name[10] = { 0 };
void add();
void setfile();
private:
char sex[5] = { 0 };
int tel;
};
当我们要读取硬盘里的数据时,采用流式读取。ios::in为打开文件,指针在开头。
void person::search_name() {
char s_name[10] = { 0 };
cout << "请输入要查询的姓名:";
cin >> s_name;
person p;
fstream file("user.txt", ios::in);
file.read((char*)&p, sizeof(p));//读取类信息
while (!file.eof()) { //判断指针是否到文件尾
if (strcmp(p.name,s_name)==0) {
p.show();
}
file.read((char*)&p, sizeof(p));
}
}
同理,不仅可以通过姓名查询,也可以通过学号,仅需改变数据成员即可。
此处需要展示的是学生姓名、学号、性别以及电话号码,所以将读出的数据,重新写入到类中,然后通过函数打印到屏幕上。
void person::show() {
cout << "姓名:" << name << endl;
cout << "学号:" << num << endl;
cout << "性别:" << sex << endl;
cout << "电话:" << tel << endl;
}
成绩录入和基本信息录入实现方式基本一致,此处为了优化读取速度,新开了一个score文件储存数据。
void student::scoreadd() {
cout << "请输入学号:";
cin >> num;
strcpy_s(tempnum, num);
cout << "\n请输入课程名称:";
cin >> cname;
cout << "\n请输入成绩:";
cin >> score;
cout << "请输入该课程学分";
cin >> credit;
}
void student::setfile() {
student s;
s.scoreadd();
fstream file("score.txt", ios::out | ios::app);
file.write((char*)&s, sizeof(s));
file.close();
cout << "保存成功" << endl;
cout << "是否继续添加 Y or F" << endl;
char continue_choose;
cin >> continue_choose;
if (continue_choose == 'y' || continue_choose == 'Y') {
s.continue_setfile();
}
}
由于写了一个是否继续添加,这时候学号需要继续使用,于是就在全局变量里设置学号。
char tempnum[15] = { 0 };
以学号为识别目标,读取该对象下的成绩,然后累计绩点和学分,从而计算出平均绩点。(平均绩点公式来源于网络,和实际有差别)
void student::search_score() {
float sum_credit=0,sum_score=0;
char s_num[15] = { 0 };
cout << "请输入要查询的学号:";
cin >> s_num;
cout << "1、查询全部成绩" << "2、查询单科成绩" << endl;
int choose;
cin >> choose;
student s;
fstream file("score.txt", ios::in);
file.read((char*)&s, sizeof(s));
if (choose == 1) {
while (!file.eof()) {
if (strcmp(s.num, s_num)==0) {
cout << s.cname << '\t' << s.score << '\t' << s.credit << endl;
sum_score +=((s.score - 50)/ 10)*s.credit;
sum_credit += s.credit;
}
file.read((char*)&s, sizeof(s));
}
cout << "平均绩点为:" << sum_score / sum_credit<<endl;
}
if (choose == 2) {
char classname[10] = { 0 };
cout << "请输入课程名称:";
cin >> classname;
while (!file.eof()) {
if (strcmp(s.num, s_num)==0&&strcmp(s.cname,classname)==0) {
cout << s.cname << '\t' << s.score << '\t' << s.credit << endl;
}
file.read((char*)&s, sizeof(s));
}
}
}