c++实现一个单门课程成绩管理系统

news/2024/10/31 2:25:14/

实验内容

实现一个单门课程成绩管理系统。进入系统时,用户可选择身份: 1.教师; 2

学生。

以教师身份进入后,如果上次已保存了数据,可将文件中数据读取出来,并

允许修改或添加新数据。如果为第一-次录入 (之前无保存的数据),则允许 教师.

录入相关数据。具体功能包括:

1.可录入或修改课程信息,包括:课程编号、课程名称;

2.可录入、修改、删除学生(数量不限)成绩,成绩项目包含两项:平时成

责、期末成绩,并按照各50%比例自动算出总成绩;学生基本信息包括学号、姓

名;示例如下:

请录入“C+ +编程”课程成绩

学号: 201901

姓名:张三

平时成绩: 60

期末成绩: 80

3.信息显示功能,可显示课程编号、课程名称、所有学生的成绩单。成绩单

格式如下:

学号

姓名

平时成绩

期末成绩

总成绩

4.信息统计功能,可显示总成绩、平时成绩、期末成绩的最高分、最低分、

平均分、在每个分数段(60分以下为-一个分数段, 60分以上每10分为- -个分数

段)的分布情况等。(选做1)

5.能够将上述数据保存在文件中,二进制、文本文件均可。

6.可读取上述文件。

以学生身份进入后,如果已保存了成绩数据,可将文件中数据读取出来,并

允许查询。如果尚无保存数据,提示尚无成绩信息。具体功能包括:

1.信息显示功能,可显示课程编号、课程名称、所有学生的成绩单。

2.信息统计功能,可显示总成绩、平时成绩、期末成绩的最高分、最低分、

平均分、在每个分数段(60分以下为-一个分数段,60分以上每10分为- -个分数

段)的分布情况等。

3.信息查询功能,输入学号或者姓名,均能进行该学生的成绩查询,并给出

该学生总成绩、平时成绩、期末成绩在全班的排名。(选做2)

选做3:

增加教师身份的密码保护功能,具体要求如下:

1.教师身份需要密码保护。选择教师身份进入系统后,必须输入密码;密码验

证无误后,才可进入后续过程。

2. 教师的密码经过加密后,存储在一 一个密码文件中。

教师的初始密码为“123456",首次进入系统时,要求用户修改密码。

4. 在后续使用中,允许修改教师密码。密码修改后,更新密码文件。

特选

5.输入密码或修改密码时,密码本身不显示出来,而是以掩码“*”显示。

实验步骤

第1步:理解需求,进行系统总体设计

第2步:进行类的设计,并予以实现

第3步:完成主函数,实现全部功能

三 解答

这个综合实验的任务比较复杂,需要设计多个类和函数来实现。在设计之前,我们可以先将整个系统分为三个模块:教师模块、学生模块和密码保护模块。其中,教师模块和学生模块的功能比较相似,可以使用同一个类来实现;密码保护模块需要单独设计一个类来实现。

下面是一个简单的实现示例:

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <iomanip>
#include <algorithm>
using namespace std;// 学生类,包含学号、姓名和成绩信息
class Student {
public:string id;      // 学号string name;    // 姓名double score1;  // 平时成绩double score2;  // 期末成绩double total;   // 总成绩Student(string i, string n, double s1 = 0, double s2 = 0) : id(i), name(n), score1(s1), score2(s2) {total = (score1 + score2) / 2.0;}// 重载小于运算符,用于排序bool operator<(const Student& other) const {return total > other.total;}
};// 课程类,包含课程编号、课程名称和学生信息
class Course {
public:string code;                // 课程编号string name;                // 课程名称vector<Student> students;   // 学生信息Course(string c, string n) : code(c), name(n) {}// 添加学生信息void addStudent(Student s) {students.push_back(s);}// 修改学生信息void modifyStudent(string id, double s1, double s2) {for (int i = 0; i < students.size(); i++) {if (students[i].id == id) {students[i].score1 = s1;students[i].score2 = s2;students[i].total = (s1 + s2) / 2.0;return;}}cout << "学号为 " << id << " 的学生不存在!" << endl;}// 删除学生信息void deleteStudent(string id) {for (int i = 0; i < students.size(); i++) {if (students[i].id == id) {students.erase(students.begin() + i);return;}}cout << "学号为 " << id << " 的学生不存在!" << endl;}// 显示所有学生信息void showStudents() {cout << "课程编号:" << code << endl;cout << "课程名称:" << name << endl;cout << "学号\t姓名\t平时成绩\t期末成绩\t总成绩" << endl;for (int i = 0; i < students.size(); i++) {cout << students[i].id << "\t" << students[i].name << "\t";cout << fixed << setprecision(2) << students[i].score1 << "\t\t" << students[i].score2 << "\t\t" << students[i].total << endl;}}// 统计信息void statistics() {int count = students.size();double sum1 = 0, sum2 = 0, sum3 = 0;double max1 = 0, max2 = 0, max3 = 0;double min1 = 100, min2 = 100, min3 = 100;int cnt1[7] = {0}, cnt2[11] = {0};if (count == 0) {cout << "没有学生信息!" << endl;return;}for (int i = 0; i < count; i++) {sum1 += students[i].score1;sum2 += students[i].score2;sum3 += students[i].total;max1 = max(max1, students[i].score1);max2 = max(max2, students[i].score2);max3 = max(max3, students[i].total);min1 = min(min1, students[i].score1);min2 = min(min2, students[i].score2);min3 = min(min3, students[i].total);if (students[i].total < 60) {cnt1[0]++;} else {cnt1[(int)(students[i].total - 60) / 10 + 1]++;}if (students[i].score1 < 60) {cnt2[0]++;} else {cnt2[(int)(students[i].score1 - 60) / 10 + 1]++;}if (students[i].score2 < 60) {cnt2[0]++;} else {cnt2[(int)(students[i].score2 - 60) / 10 + 1]++;}}double avg1 = sum1 / count;double avg2 = sum2 / count;double avg3 = sum3 / count;cout << "总成绩:" << endl;cout << "最高分:" << max3 << endl;cout << "最低分:" << min3 << endl;cout << "平均分:" << avg3 << endl;cout << "分数段分布情况:" << endl;cout << "<60: " << cnt1[0] << endl;for (int i = 1; i <= 10; i++) {cout << i * 10 << "-" << i * 10 + 9 << ": " << cnt1[i] << endl;}cout << "平时成绩:" << endl;cout << "最高分:" << max1 << endl;cout << "最低分:" << min1 << endl;cout << "平均分:" << avg1 << endl;cout << "分数段分布情况:" << endl;cout << "<60: " << cnt2[0] << endl;for (int i = 1; i <= 10; i++) {cout << i * 10 << "-" << i * 10 + 9 << ": " << cnt2[i] << endl;}cout << "期末成绩:" << endl;cout << "最高分:" << max2 << endl;cout << "最低分:" << min2 << endl;cout << "平均分:" << avg2 << endl;cout << "分数段分布情况:" << endl;cout << "<60: " << cnt2[0] << endl;for (int i = 1; i <= 10; i++) {cout << i * 10 << "-" << i * 10 + 9 << ": " << cnt2[i] << endl;}}
};// 教师类,包含课程信息和学生信息管理功能
class Teacher {
public:string password;    // 密码Course course;      // 课程信息// 构造函数,从文件中读取数据Teacher(string c, string n) : course(c, n) {ifstream ifs("data.bin", ios::binary);if (!ifs) {cout << "没有保存的数据!" << endl;return;}while (true) {Student s("", "");ifs.read((char*)&s, sizeof(Student));if (ifs.eof()) {break;}course.addStudent(s);}ifs.close();}// 添加学生信息void addStudent(string id, string name, double s1, double s2) {Student s(id, name, s1, s2);course.addStudent(s);cout << "添加学生信息成功!" << endl;}// 修改学生信息void modifyStudent(string id, double s1, double s2) {course.modifyStudent(id, s1, s2);}// 删除学生信息void deleteStudent(string id) {course.deleteStudent(id);}// 显示所有学生信息void showStudents() {course.showStudents();}// 统计信息void statistics() {course.statistics();}// 保存数据到文件void saveData() {ofstream ofs("data.bin", ios::binary);for (int i = 0; i < course.students.size(); i++) {ofs.write((char*)&course.students[i], sizeof(Student));}ofs.close();cout << "数据保存成功!" << endl;}
};// 学生类,包含查询成绩信息
class Student {
public:string id;          // 学号string name;        // 姓名vector<Course*> courses;    // 所选课程指针列表Student(string i, string n) : id(i), name(n) {}// 添加所选课程void addCourse(Course* c) {courses.push_back(c);}// 查询成绩信息void queryScore() {cout << "学生姓名:" << name << endl;for (int i = 0; i < courses.size(); i++) {cout << "课程名称:" << courses[i]->name << endl;cout << "平时成绩:" << findScore(id, courses[i]->students, 1) << endl;cout << "期末成绩:" << findScore(id, courses[i]->students, 2) << endl;cout << "总成绩:" << findScore(id, courses[i]->students, 3) << endl;}}private:// 查找指定学生的成绩double findScore(string id, vector<Student>& students, int type) {for (int i = 0; i < students.size(); i++) {if (students[i].id == id) {switch (type) {case 1:return students[i].score1;case 2:return students[i].score2;case 3:return students[i].total;}}}return -1;  // 没有找到对应学生的成绩}
};const int MAX_TEACHERS = 100; // 最大教师数量
const int PASSWORD_LENGTH = 6; // 密码长度//密码保护模块的示例代码,包括密码加密、验证和修改功能。在本示例中,我们使用了数组来存储密码文件中的加密后的密码,并且通过类来封装密码保护模块的功能。
class PasswordProtector {
private:char encrypted_password[PASSWORD_LENGTH+1]; // 存储加密后的密码
public:PasswordProtector() { // 构造函数,将初始密码“123456”加密并存储encrypt("123456");}bool verifyPassword(char* password) { // 验证密码是否正确char encrypted_input[PASSWORD_LENGTH+1];encrypt(password, encrypted_input);return strcmp(encrypted_input, encrypted_password) == 0;}void changePassword(char* new_password) { // 修改密码encrypt(new_password);updatePasswordFile();}
private:void encrypt(char* password, char* output = NULL) { // 加密函数if (output == NULL) output = encrypted_password;for (int i = 0; i < PASSWORD_LENGTH; i++) {output[i] = password[i] ^ 0x5A;}output[PASSWORD_LENGTH] = '\0';}void updatePasswordFile() { // 更新密码文件(这里用输出到控制台代替)cout << "密码文件已更新" << endl;}
};class TeacherManager {
private:Teacher teachers[MAX_TEACHERS];int teacher_count;PasswordProtector password_protector;
public:TeacherManager() { // 构造函数,初始化教师数量为0teacher_count = 0;}void addTeacher(Teacher t) { // 添加教师teachers[teacher_count++] = t;}bool login() { // 登录系统char password[PASSWORD_LENGTH+1];cout << "请输入密码:";for (int i = 0; i < PASSWORD_LENGTH; i++) {password[i] = getchar();putchar('*');}password[PASSWORD_LENGTH] = '\0';cout << endl;return password_protector.verifyPassword(password);}void changePassword() { // 修改密码char password[PASSWORD_LENGTH+1];cout << "请输入原密码:";for (int i = 0; i < PASSWORD_LENGTH; i++) {password[i] = getchar();putchar('*');}password[PASSWORD_LENGTH] = '\0';cout << endl;if (!password_protector.verifyPassword(password)) {cout << "密码错误,无法修改" << endl;return;}cout << "请输入新密码:";for (int i = 0; i < PASSWORD_LENGTH; i++) {password[i] = getchar();putchar('*');}password[PASSWORD_LENGTH] = '\0';cout << endl;password_protector.changePassword(password);}
};


http://www.ppmy.cn/news/252332.html

相关文章

软件开发报价的计算方法(转载)

软件开发报价的计算方法 (转载&#xff09; 1&#xff0e;软件开发价格估算方法 软件开发价格与工作量、商务成本、国家税收和企业利润等项有关。为了便于计算&#xff0c;给出一个计算公式&#xff1a; 软件开发价格 &#xff1d; 开发工作量 开发费用&#xff0f;人月 1.1开…

自己换了空调滤芯,终于告别了泥土味

车开一年了&#xff0c;味道越来越大&#xff0c;只是一直苦于没时间&#xff0c;本周正好要保养了&#xff0c;下定决心一定要换掉&#xff0c;在TB买了两块空调滤&#xff0c;一块换&#xff0c;一块留着以后用&#xff0c;又买了一套螺丝刀&#xff0c;和一瓶空调管道清洗液…

软件开发报价的计算方法[转载]

1&#xff0e;软件开发价格估算方法 软件开发价格与工作量、商务成本、国家税收和企业利润等项有关。为了便于计算&#xff0c;给出一个计算公式&#xff1a; 软件开发价格 &#xff1d; 开发工作量 开发费用&#xff0f;人月 1.1开发工作量 软件开发工作量与估算工作量经验值…

格力与奥克斯空调在京东的选购指数(java爬虫案例-代码实现)

要么不做&#xff0c;要做就做完 此项目目录结构 项目分析 环境准备 开发准备 数据库表 添加依赖 添加配置文件 编写pojo 编写dao 编写service接口 service实现类 StringBoot引导类 封装Htmlunit 实现数据抓取 成功展示 这前段时间有一件事“格力举报奥克斯空调质…

不平衡报价的对策分析

正好赶上了个不平衡报价非常好的案例&#xff0c;和大家一起分析下。 先说什么是不平衡报价 不平衡报价法是相对通常的平衡报价(正常报价)而言的&#xff0c;是在工程项目的投标总价确定后&#xff0c;根据招标文件的付款条件&#xff0c;合理地调整投标文件中子项目的报价&…

SpringCloud-stream一体化MQ解决方案-基本配置篇

参考资料: 参考demo 参考视频1 参考视频2 官方文档(推荐) 官方文档中文版 关于Kafka和rabbitMQ的安装教程,见本人之前的博客 rocketMq的安装教程 rocketMq仪表盘安装教程 重!!!

软件开发报价

1&#xff0e;软件开发价格估算方法 软件开发价格与工作量、商务成本、国家税收和企业利润等项有关。为了便于计算&#xff0c;给出一个计算公式&#xff1a; 软件开发价格 &#xff1d; 开发工作量 开发费用&#xff0f;人月 1.1开发工作量 软件开发工作量与估算工…

不可不知的设计师接活报价公式

其实原本就打算第七章写一下关于设计师外包单报价、合同、和愉快合作完美截稿的事&#xff0c;不过之前一直忙于参加比赛&#xff0c;搁浅了。这几天看到MartinRGB这位朋友翻译了一篇国外设计师Layervault写的《设计师外包价格参考表》&#xff0c;感触良多&#xff0c;决定放下…