From a3fd355bf6993ba84fd6389589c5aa1dab8e62ac Mon Sep 17 00:00:00 2001 From: qding98 <3130093892@qq.com> Date: Mon, 30 Jun 2025 17:21:13 +0800 Subject: [PATCH] Add files via upload --- mana_code/SCHOOL_MANAGEMENT_SYSTEM.cpp | 427 +++++++++++++++++++++++++ mana_code/creategradeini.cpp | 196 ++++++++++++ mana_code/db_storage.h | 258 +++++++++++++++ mana_code/global_data.cpp | 8 + mana_code/global_data.h | 9 + mana_code/global_data1.h | 8 + mana_code/global_data2.cpp | 5 + mana_code/global_data2.h | 9 + mana_code/global_data3.cpp | 5 + mana_code/global_data3.h | 5 + mana_code/mana_Class.h | 177 ++++++++++ mana_code/mana_Course.h | 74 +++++ mana_code/mana_Person.h | 26 ++ mana_code/mana_Student.h | 230 +++++++++++++ mana_code/mana_Teacher.h | 194 +++++++++++ mana_code/mana_adm.h | 171 ++++++++++ mana_code/mana_ini.h | 114 +++++++ 17 files changed, 1916 insertions(+) create mode 100644 mana_code/SCHOOL_MANAGEMENT_SYSTEM.cpp create mode 100644 mana_code/creategradeini.cpp create mode 100644 mana_code/db_storage.h create mode 100644 mana_code/global_data.cpp create mode 100644 mana_code/global_data.h create mode 100644 mana_code/global_data1.h create mode 100644 mana_code/global_data2.cpp create mode 100644 mana_code/global_data2.h create mode 100644 mana_code/global_data3.cpp create mode 100644 mana_code/global_data3.h create mode 100644 mana_code/mana_Class.h create mode 100644 mana_code/mana_Course.h create mode 100644 mana_code/mana_Person.h create mode 100644 mana_code/mana_Student.h create mode 100644 mana_code/mana_Teacher.h create mode 100644 mana_code/mana_adm.h create mode 100644 mana_code/mana_ini.h diff --git a/mana_code/SCHOOL_MANAGEMENT_SYSTEM.cpp b/mana_code/SCHOOL_MANAGEMENT_SYSTEM.cpp new file mode 100644 index 0000000..fee324f --- /dev/null +++ b/mana_code/SCHOOL_MANAGEMENT_SYSTEM.cpp @@ -0,0 +1,427 @@ +#include "mana_adm.h" +#include"db_storage.h" +#include +using namespace std; +unordered_map adminmap; +unordered_map studentmap; +unordered_map teachermap; +unordered_map coursemap; +unordered_map classmap; +// 系统反馈的错误输出要在主程序中,每一次高一层的对象在改变数据时,都要对低一层的类进行维护 +// 类的结构course->student->class->teacher->administrator +// 全局数据结构 +// 学号开头为@+数字 +// 教师工号开头为#+数字 +// 课程编号开头为$+英语 +// 班级编号开头为%+数字 +// 管理员账号开头为& +void initGlobalData() { + // 初始化管理员 + // 初始化班级 + adminmap["&admin"] = Administrator("唐洪武", "男"); + Administrator admin = adminmap["&admin"]; + admin.addClass("%数学自动化"); + admin.addClass("%计算机科学"); + admin.addClass("%软件工程"); + // 初始化学生 + admin.addStudent(new Student("@20240001", "张三", "男", "%数学自动化")); + admin.addStudent(new Student("@20240002", "李四", "女", "%计算机科学")); + admin.addStudent(new Student("@20240003", "王五", "男", "%软件工程")); + admin.addStudent(new Student("@20240004", "赵六", "女", "%数学自动化")); + admin.addStudent(new Student("@20240005", "钱七", "男", "%计算机科学")); + admin.addStudent(new Student("@20240006", "孙八", "女", "%软件工程")); + // 初始化课程 + admin.addCourse(new Course("$math_analysis", "数学分析", false, 1, 1, 2, 4)); + admin.addCourse(new Course("$data_structure", "数据结构", true, 2, 1, 2, 3)); + admin.addCourse(new Course("$computer_network", "计算机网络", true, 3, 1, 2, 3)); + admin.addCourse(new Course("$operating_system", "操作系统", true, 4, 1, 2, 3)); + admin.addCourse(new Course("$machine_learning", "机器学习", true, 5, 1, 2, 3)); + //初始化老师 + admin.addTeacher(new Teacher("#001", "张东升", "男")); + admin.addTeacher(new Teacher("#002", "李小红", "女")); + admin.addTeacher(new Teacher("#003", "王伟", "男")); + // 初始化必修课 + admin.setCourseMandatory("$math_analysis", "%数学自动化"); + admin.setCourseMandatory("$data_structure", "%计算机科学"); + admin.setCourseMandatory("$computer_network", "%软件工程"); + //初始化教师教学课程 + admin.assignCourseToTeacher("$math_analysis", "#001"); + admin.assignCourseToTeacher("$data_structure", "#002"); + admin.assignCourseToTeacher("$computer_network", "#003"); +} +int main(){ + // --- 新增:尝试读取本地数据库 --- + loadStudents("students.ini", studentmap); + loadTeachers("teachers.ini", teachermap); + loadCourses("courses.ini", coursemap); + loadClasses("classes.ini", classmap); + + // 如果数据库为空,才初始化默认数据 + if (studentmap.empty() || teachermap.empty() || coursemap.empty() || classmap.empty()) { + initGlobalData(); + } + else { + adminmap["&admin"] = Administrator("唐洪武", "男"); + cout<<"文件读取成功!"<> state; + + // 处理退出 + if(state == 0){ + cout << "感谢使用,再见!" << endl; + break; // 退出整个程序 + } + int times=0; // 记录循环次数,防止死循环 + // 处理学生端 + if(state == 1) { + string id, name, className; + // 学生登录循环 + while(true){ + cout << "请输入您的学号,姓名和班级(输入0返回主菜单)" << endl; + cin >> id; + if(id == "0") break; // 返回主菜单 + cin >> name >> className; + + if(studentmap.find(id) != studentmap.end()) { + Student& student = studentmap[id]; + if(student.getName() == name && student.getClassName() == className) { + cout << "欢迎," << name << "!您已成功登录学生端。" << endl; + + // 学生功能循环 + while(true){ + cout << "选修课程请按1,退选课程请按2,查看成绩请按3,打印课表请按4,退出请按0" << endl; + int choice; + cin >> choice; + + if(choice == 0) { + cout << "退出学生端。" << endl; + break; // 退出学生功能循环 + } + else if(choice == 1) { + cout << "请输入要选修的课程编号:" << endl; + string courseId; + cin >> courseId; + student.selectCourse(courseId); + cout << "课程 " << courseId << " 已选修。" << endl; + } + else if(choice == 2) { + cout << "请输入要退选的课程编号:" << endl; + string courseId; + cin >> courseId; + student.dropCourse(courseId); + cout << "课程 " << courseId << " 已退选。" << endl; + } + else if(choice == 3) { + student.print_grade(); + cout << "您的成绩已打印。" << endl; + } + else if(choice == 4) { + student.printTimetable(); + } + else { + cout << "无效的选择,请重新输入。" << endl; + } + } + break; // 成功登录并退出后跳出登录循环 + } + else { + cout << "学号、姓名或班级信息不匹配,请重新输入。" << endl; + } + } + else { + cout << "学号不存在,请重新输入。" << endl; + times++; + if(times >= 3) { + alltimes++; + cout << "连续三次输入错误,返回主菜单。" << endl; + break; // 返回主菜单 + } + } + } + } + // 处理教师端 + else if(state == 2) { + string id, name; + // 教师登录循环 + while(true){ + cout << "请输入您的工号,姓名(输入0返回主菜单)" << endl; + cin >> id; + if(id == "0") break; // 返回主菜单 + cin >> name; + + if(teachermap.find(id) != teachermap.end()) { + Teacher& teacher = teachermap[id]; + if(teacher.getName() == name) { + cout << "欢迎," << name << "!您已成功登录教师端。" << endl; + + // 教师功能循环 + while(true){ + cout << "查看课表请按1,通过文件读取设置成绩请按2,查询基本信息请按3,设置单个学生成绩请按4,按照班级查询课程成绩请按5,退出请按0" << endl; + int choice; + cin >> choice; + + if(choice == 0) { + cout << "退出教师端。" << endl; + break; // 退出教师功能循环 + } + else if(choice == 1) { + teacher.printTimetable(); + } + else if(choice == 2) { + cout << "请输入课程编号系统将自动读取以课程编号命名的ini文件(格式:课程编号 ):" << endl; + string courseId; + cin >> courseId; + //采用文件读取的方式读取成绩 + teacher.teacherreadCourseGrades(courseId); + teachermap[id]=teacher; // 更新教师信息 + } + else if(choice == 3) { + teacher.getidnamegender(); + cout << "负责的课程:" << endl; + for(const string& course : teacher.getAssignedCourses()) { + cout << course << endl; + } + } + else if(choice == 4) { + cout << "请输入课程编号、学生学号和成绩(格式:课程编号 学生学号 成绩):" << endl; + string courseId, studentId; + double grade; + cin >> courseId >> studentId >> grade; + teacher.setGradeForStudent(courseId, studentId, grade); + } + else if(choice == 5) { + cout << "请输入班级编号(格式:班级编号):" << endl; + string className; + cin >> className; + if(classmap.find(className) != classmap.end()) { + teacher.printCourseGradesByClass(className); // 打印班级成绩 + } else { + cout << "班级不存在,请重新输入。" << endl; + } + } + else { + cout << "无效的选择,请重新输入。" << endl; + } + } + break; // 成功登录并退出后跳出登录循环 + } + else { + cout << "工号或姓名信息不匹配,请重新输入。" << endl; + } + } + else { + cout << "工号不存在,请重新输入。" << endl; + times++; + if(times >= 3) { + alltimes++; + cout << "连续三次输入错误,返回主菜单。" << endl; + break; // 返回主菜单 + } + } + } + } + // 处理管理员端 + else if(state == 3) { + // 管理员登录循环 + while(true){ + cout << "请输入管理员账号和姓名(输入0返回主菜单)" << endl; + string adminId, adminName; + cin >> adminId; + if(adminId == "0") break; // 返回主菜单 + cin >> adminName; + + if(adminmap.find(adminId) != adminmap.end()) { + Administrator& admin = adminmap[adminId]; + if(admin.getName() == adminName) { + cout << "欢迎," << adminName << "!您已成功登录管理员端。" << endl; + + // 管理员功能循环 + while(true){ + cout << "请输入你的选择" << endl; + cout << "1. 添加学生" << endl; + cout << "2. 添加教师" << endl; + cout << "3. 添加课程" << endl; + cout << "4. 设置课程为某班级必修课" << endl; + cout << "5. 分配课程给教师" << endl; + cout << "6. 排课" << endl; + cout << "7. 打印班级成绩" << endl; + cout << "8. 将班级按照学生平均分排序" << endl; + cout << "9. 添加班级" << endl; + cout<<"10. 查看某班级所有学生的课程成绩(包含选修课)"<> choice; + + if(choice == 0) { + cout << "退出管理员端。" << endl; + break; // 退出管理员功能循环 + } + else if(choice == 1) { + cout << "请输入学生信息(学号 姓名 性别 班级):" << endl; + string id, name,gender, className; + cin >> id >> name >>gender >> className; + if(studentmap.find(id) == studentmap.end()) { + Student newStudent(id,name,gender, className); + admin.addStudent(&newStudent); + cout << "学生 " << name << " 已添加成功。" << endl; + } else { + cout << "学号已存在,请重新输入。" << endl; + } + } + else if(choice == 2) { + cout << "请输入教师信息(工号 姓名 性别):" << endl; + string id, name,gender; + cin >> id >> name >>gender; + if(teachermap.find(id) == teachermap.end()) { + Teacher newTeacher(id,name,gender); + if(teachermap.find(id) == teachermap.end()) { + admin.addTeacher(&newTeacher); + cout << "教师 " << name << " 已添加成功。" << endl; + } else { + cout << "工号已存在,请重新输入。" << endl; + } + } + } + else if(choice == 3) { + cout << "请输入课程信息(课程编号 课程名称 是否选修 课程日期 开始时间 结束时间 学分):" << endl; + string id, name; + bool isElective; + int day, st, ed, val; + cin >> id >> name >> isElective >> day >> st >> ed >> val; + if(coursemap.find(id) == coursemap.end()) { + Course newCourse(id, name, isElective, day, st, ed, val); + admin.addCourse(&newCourse); + cout << "课程 " << name << " 已添加成功。" << endl; + } else { + cout << "课程编号已存在,请重新输入。" << endl; + } + } + else if(choice == 4) { + cout << "请输入课程编号和班级编号(格式:课程编号 班级编号):" << endl; + string courseId, className; + cin >> courseId >> className; + admin.setCourseMandatory(courseId, className); + cout << "课程 " << courseId << " 已设置为班级 " << className << " 的必修课。" << endl; + } + else if(choice == 5) { + cout << "请输入课程编号和教师工号(格式:课程编号 教师工号):" << endl; + string courseId, teacherId; + cin >> courseId >> teacherId; + admin.assignCourseToTeacher(courseId, teacherId); + cout << "课程 " << courseId << " 已分配给教师 " << teacherId << "。" << endl; + } + else if(choice == 6) { + cout << "请输入课程编号、日期、开始时间和结束时间(格式:课程编号 日期 开始时间 结束时间):" << endl; + string courseId; + int date, st, ed; + cin >> courseId >> date >> st >> ed; + admin.scheduleCourseTime(courseId, date, st, ed); + cout << "课程 " << courseId << " 已排定在日期 " << date << ",时间段 " << st << "-" << ed << "." << endl; + } + else if(choice == 7) { + cout << "请输入班级编号:" << endl; + string className; + cin >> className; + admin.printClassGrades(className); + } + else if(choice == 8) { + admin.sortClassesByAverage(); + } + else if(choice == 9) { + cout << "请输入班级名称:" << endl; + string className; + cin >> className; + if(classmap.find(className) == classmap.end()) { + admin.addClass(className); + cout << "班级 " << className << " 已添加成功。" << endl; + } else { + cout << "班级已存在,请重新输入。" << endl; + } + } + else if(choice == 10) { + cout << "请输入班级编号:" << endl; + string className; + cin >> className; + if(classmap.find(className) != classmap.end()) { + admin.inquireClassAllGrades(className); + } else { + cout << "班级不存在,请重新输入。" << endl; + } + } + else if(choice == 11) { + cout << "请输入要删除的学生学号:" << endl; + string studentId; + cin >> studentId; + admin.removeStudent(studentId); + } + else if(choice == 12) { + cout << "请输入要删除的教师工号:" << endl; + string teacherId; + cin >> teacherId; + admin.removeTeacher(teacherId); + } + else if(choice == 13) { + cout << "请输入学生学号和新的姓名、性别、班级(格式:学号 姓名 性别 班级):" << endl; + string studentId, newName, newGender, newClassName; + cin >> studentId >> newName >> newGender >> newClassName; + admin.modifyStudent(studentId, newName, newGender, newClassName); + } + else if(choice == 14) { + cout << "请输入教师工号和新的姓名、性别(格式:工号 姓名 性别):" << endl; + string teacherId, newName, newGender; + cin >> teacherId >> newName >> newGender; + admin.modifyTeacher(teacherId, newName, newGender); + } + else { + cout << "无效的选择,请重新输入。" << endl; + } + } + break; // 成功登录并退出后跳出登录循环 + } + else { + cout << "管理员姓名不匹配,请重新输入。" << endl; + } + } + else { + cout << "管理员账号不存在,请重新输入。" << endl; + times++; + if(times >= 3) { + alltimes++; + cout << "连续三次输入错误,返回主菜单。" << endl; + break; // 返回主菜单 + } + } + } + } + // 处理无效输入 + else { + cout << "无效的输入,请重新选择端口(1-学生端, 2-教师端, 3-管理员端, 0-退出)" << endl; + } + // 检查是否连续十次输入错误 + if(alltimes >= 10) { + cout << "连续十次输入错误,程序将退出。" << endl; + break; // 退出整个程序 + } + } + // --- 新增:保存数据到本地数据库 --- + saveStudents("students.ini", studentmap); + saveTeachers("teachers.ini", teachermap); + saveCourses("courses.ini", coursemap); + saveClasses("classes.ini", classmap); + return 0; +} \ No newline at end of file diff --git a/mana_code/creategradeini.cpp b/mana_code/creategradeini.cpp new file mode 100644 index 0000000..79eb01b --- /dev/null +++ b/mana_code/creategradeini.cpp @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include +#include +using namespace std; + +class INIWriter { +private: + string filename; + map> config; + vector sectionOrder; // 保持节的原始顺序 + + // 解析INI文件内容到config结构 + void parseContent(const vector& lines) { + string currentSection = ""; + + for (const auto& line : lines) { + string trimmed = trim(line); + if (trimmed.empty() || trimmed[0] == ';' || trimmed[0] == '#') { + continue; // 跳过注释和空行 + } + + if (trimmed[0] == '[' && trimmed.back() == ']') { + currentSection = trimmed.substr(1, trimmed.size() - 2); + if (config.find(currentSection) == config.end()) { + sectionOrder.push_back(currentSection); + } + } else { + size_t pos = trimmed.find('='); + if (pos != string::npos) { + string key = trim(trimmed.substr(0, pos)); + string value = trim(trimmed.substr(pos + 1)); + if (!currentSection.empty() && !key.empty()) { + config[currentSection][key] = value; + } + } + } + } + } + + // 辅助函数:去除字符串两端空白 + string trim(const string& str) { + size_t first = str.find_first_not_of(" \t"); + if (first == string::npos) return ""; + size_t last = str.find_last_not_of(" \t"); + return str.substr(first, (last - first + 1)); + } + +public: + INIWriter() {} + + // 设置INI文件名(用于后续操作) + void setFileName(const string& name) { + filename = name; + } + + // 读取INI文件到内存 + bool readFile() { + ifstream file(filename); + if (!file.is_open()) { + cout << "Unable to open file: " << filename << endl; + return false; + } + + vector lines; + string line; + while (getline(file, line)) { + lines.push_back(line); + } + file.close(); + + config.clear(); + sectionOrder.clear(); + parseContent(lines); + return true; + } + + // 写入INI文件 + bool writeFile() { + if (filename.empty()) { + cout << "Filename not set" << endl; + return false; + } + + ofstream file(filename); + if (!file.is_open()) { + cout << "Unable to open file: " << filename << endl; + return false; + } + + for (const auto& section : sectionOrder) { + if (config.find(section) != config.end()) { + file << "[" << section << "]" << endl; + for (const auto& kv : config[section]) { + file << kv.first << "=" << kv.second << endl; + } + file << endl; // 节之间添加空行 + } + } + + file.close(); + cout << "File written: " << filename << endl; + return true; + } + + // 设置值 + void setValue(const string& section, const string& key, const string& value) { + if (config.find(section) == config.end()) { + sectionOrder.push_back(section); // 添加新节到顺序列表 + } + config[section][key] = value; + } + + // 删除整个节 + bool removeSection(const string& section) { + auto secIt = config.find(section); + if (secIt != config.end()) { + config.erase(secIt); + + // 从顺序列表中移除 + auto pos = find(sectionOrder.begin(), sectionOrder.end(), section); + if (pos != sectionOrder.end()) { + sectionOrder.erase(pos); + } + return true; + } + return false; + } + + // 删除特定键 + bool removeKey(const string& section, const string& key) { + auto secIt = config.find(section); + if (secIt != config.end()) { + auto& keyMap = secIt->second; + auto keyIt = keyMap.find(key); + if (keyIt != keyMap.end()) { + keyMap.erase(keyIt); + return true; + } + } + return false; + } +}; + +int main() { + INIWriter writer; + string filename; + cout << "Enter filename (without extension): "; + cin >> filename; + writer.setFileName(filename + ".ini"); + + // 1. 先创建文件(如果不存在) + if (!writer.writeFile()) { + cerr << "Failed to create file!" << endl; + return 1; + } + + // 2. 读取文件 + if(!writer.readFile()) { + cerr << "Failed to read file!" << endl; + return 1; + } + + cout << "File read successfully." << endl; + + // 3. 设置新值 + cin.ignore(); // 清除输入缓冲区 + + while (true) { + string section, key, value; + + cout << "\nEnter section name (or 'exit' to quit): "; + getline(cin, section); + if (section == "exit") break; + + cout << "Enter key: "; + getline(cin, key); + + cout << "Enter value: "; + getline(cin, value); + + writer.setValue(section, key, value); + cout << "Set " << section << "." << key << " = " << value << endl; + + // 4. 立即保存更改 + if (!writer.writeFile()) { + cerr << "Failed to save changes!" << endl; + } else { + cout << "Changes saved!" << endl; + } + } + + return 0; +} \ No newline at end of file diff --git a/mana_code/db_storage.h b/mana_code/db_storage.h new file mode 100644 index 0000000..87f1a63 --- /dev/null +++ b/mana_code/db_storage.h @@ -0,0 +1,258 @@ +#ifndef DB_STORAGE_H +#define DB_STORAGE_H + +#include +#include +#include +#include +#include +#include +#include "global_data3.h" +using namespace std; + +// --- 学生 --- +inline void saveStudents(const string& filename, const unordered_map& Studentmap) { + ofstream fout(filename); + for (auto it = Studentmap.begin(); it != Studentmap.end(); ++it) { + const string& id = it->first; + const Student& stu = it->second; + fout << "[Student]" << endl; + fout << "id=" << id << endl; + fout << "name=" << stu.getName() << endl; + fout << "gender=" << stu.getGender() << endl; + fout << "class=" << stu.getClassName() << endl; + // 课程成绩 + for (auto cg_it = stu.courseGrades.begin(); cg_it != stu.courseGrades.end(); ++cg_it) { + const string& cid = cg_it->first; + double grade = cg_it->second; + fout << "grade_" << cid << "=" << fixed << setprecision(2) << grade << endl; + } + // 必修课 + for (const auto& c : stu.mancourses) { + fout << "mancourse=" << c << endl; + } + // 选修课 + for (const auto& c : stu.selectedCourses) { + fout << "selectedcourse=" << c << endl; + } + fout << endl; + } + fout.close(); +} + +inline void loadStudents(const string& filename, unordered_map& Studentmap) { + ifstream fin(filename); + if (!fin.is_open()) return; + string line, id, name, gender, classname; + Student stu; + while (getline(fin, line)) { + if (line == "[Student]") { + if (!id.empty()) Studentmap[id] = stu; + stu = Student(); + id = name = gender = classname = ""; + stu.selectedCourses.clear(); + stu.mancourses.clear(); + stu.courseGrades.clear(); + } else if (line.find("id=") == 0) { + id = line.substr(3); + stu = Student(id, "", "", ""); + } else if (line.find("name=") == 0) { + stu.setName(line.substr(5)); + } else if (line.find("gender=") == 0) { + stu.setGender(line.substr(7)); + } else if (line.find("class=") == 0) { + stu.setClassName(line.substr(6)); + } else if (line.find("grade_") == 0) { + size_t eq = line.find('='); + string cid = line.substr(6, eq-6); + double grade = stod(line.substr(eq+1)); + stu.courseGrades[cid] = grade; + } else if (line.find("mancourse=") == 0) { + stu.mancourses.insert(line.substr(10)); + } else if (line.find("selectedcourse=") == 0) { + stu.selectedCourses.insert(line.substr(15)); + } + } + if (!id.empty()) Studentmap[id] = stu; + fin.close(); +} + +// --- 教师 --- +inline void saveTeachers(const string& filename, const unordered_map& Teachermap) { + ofstream fout(filename); + for (auto it = Teachermap.begin(); it != Teachermap.end(); ++it) { + const string& id = it->first; + const Teacher& t = it->second; + fout << "[Teacher]" << endl; + fout << "id=" << id << endl; + fout << "name=" << t.getName() << endl; + fout << "gender=" << t.getGender() << endl; + for (const auto& c : t.getAssignedCourses()) { + fout << "course=" << c << endl; + } + fout << endl; + } + fout.close(); +} + +inline void loadTeachers(const string& filename, unordered_map& Teachermap) { + ifstream fin(filename); + if (!fin.is_open()) return; + string line, id, name, gender; + unordered_set courses; + while (getline(fin, line)) { + if (line == "[Teacher]") { + if (!id.empty()) { + Teacher t(id, name, gender); + for (const auto& c : courses) t.assignCourse(c); + Teachermap[id] = t; + } + id = name = gender = ""; + courses.clear(); + } else if (line.find("id=") == 0) { + id = line.substr(3); + } else if (line.find("name=") == 0) { + name = line.substr(5); + } else if (line.find("gender=") == 0) { + gender = line.substr(7); + } else if (line.find("course=") == 0) { + courses.insert(line.substr(7)); + } + } + if (!id.empty()) { + Teacher t(id, name, gender); + for (const auto& c : courses) t.assignCourse(c); + Teachermap[id] = t; + } + fin.close(); +} + +// --- 课程 --- +inline void saveCourses(const string& filename, const unordered_map& Coursemap) { + ofstream fout(filename); + for (unordered_map::const_iterator it = Coursemap.begin(); it != Coursemap.end(); ++it) { + const string& id = it->first; + const Course& c = it->second; + fout << "[Course]" << endl; + fout << "id=" << id << endl; + fout << "name=" << c.getCourseName() << endl; + fout << "isElective=" << c.getIsElective() << endl; + fout << "day=" << c.getday() << endl; + fout << "st=" << c.getst() << endl; + fout << "ed=" << c.geted() << endl; + fout << "val=" << c.getval() << endl; + fout << "teacher=" << c.getAssignedTeacher() << endl; + for (const auto& cls : c.outmanclass()) { + fout << "mandatoryForClass=" << cls << endl; + } + for (const auto& stu : c.outstu()) { + fout << "selectstu=" << stu << endl; + } + fout << endl; + } + fout.close(); +} + +inline void loadCourses(const string& filename, unordered_map& Coursemap) { + ifstream fin(filename); + if (!fin.is_open()) return; + string line, id, name, teacher; + bool isElective = false; + int day = 0, st = 0, ed = 0, val = 0; + unordered_set manclass, selectstu; + while (getline(fin, line)) { + if (line == "[Course]") { + if (!id.empty()) { + Course c(id, name, isElective, day, st, ed, val); + for (const auto& cls : manclass) c.setMandatoryForClass(cls); + for (const auto& stu : selectstu) c.stu_select(stu); + c.assign_teach(teacher); + Coursemap[id] = c; + } + id = name = teacher = ""; + isElective = false; day = st = ed = val = 0; + manclass.clear(); selectstu.clear(); + } else if (line.find("id=") == 0) { + id = line.substr(3); + } else if (line.find("name=") == 0) { + name = line.substr(5); + } else if (line.find("isElective=") == 0) { + isElective = (line.substr(11) == "1" || line.substr(11) == "true"); + } else if (line.find("day=") == 0) { + day = stoi(line.substr(4)); + } else if (line.find("st=") == 0) { + st = stoi(line.substr(3)); + } else if (line.find("ed=") == 0) { + ed = stoi(line.substr(3)); + } else if (line.find("val=") == 0) { + val = stoi(line.substr(4)); + } else if (line.find("teacher=") == 0) { + teacher = line.substr(8); + } else if (line.find("mandatoryForClass=") == 0) { + manclass.insert(line.substr(17)); + } else if (line.find("selectstu=") == 0) { + selectstu.insert(line.substr(10)); + } + } + if (!id.empty()) { + Course c(id, name, isElective, day, st, ed, val); + for (const auto& cls : manclass) c.setMandatoryForClass(cls); + for (const auto& stu : selectstu) c.stu_select(stu); + c.assign_teach(teacher); + Coursemap[id] = c; + } + fin.close(); +} + +// --- 班级 --- +inline void saveClasses(const string& filename, const unordered_map& Classmap) { + ofstream fout(filename); + for (unordered_map::const_iterator it = Classmap.begin(); it != Classmap.end(); ++it) { + const string& id = it->first; + const Clas& c = it->second; + fout << "[Class]" << endl; + fout << "id=" << id << endl; + for (const auto& stu : c.getStudents()) { + fout << "student=" << stu << endl; + } + for (const auto& course : c.getcou()) { + fout << "mancourse=" << course << endl; + } + fout << endl; + } + fout.close(); +} + +inline void loadClasses(const string& filename, unordered_map& Classmap) { + ifstream fin(filename); + if (!fin.is_open()) return; + string line, id; + unordered_set students, mancourses; + while (getline(fin, line)) { + if (line == "[Class]") { + if (!id.empty()) { + Clas c(id); + for (const auto& stu : students) c.addStudent(stu); + for (const auto& course : mancourses) c.addMandatoryCourse(course); + Classmap[id] = c; + } + id = ""; + students.clear(); mancourses.clear(); + } else if (line.find("id=") == 0) { + id = line.substr(3); + } else if (line.find("student=") == 0) { + students.insert(line.substr(8)); + } else if (line.find("mancourse=") == 0) { + mancourses.insert(line.substr(10)); + } + } + if (!id.empty()) { + Clas c(id); + for (const auto& stu : students) c.addStudent(stu); + for (const auto& course : mancourses) c.addMandatoryCourse(course); + Classmap[id] = c; + } + fin.close(); +} + +#endif // DB_STORAGE_H \ No newline at end of file diff --git a/mana_code/global_data.cpp b/mana_code/global_data.cpp new file mode 100644 index 0000000..d271303 --- /dev/null +++ b/mana_code/global_data.cpp @@ -0,0 +1,8 @@ +#include +#include +#include"global_data.h" +std::unordered_map coursemap; +std::unordered_map studentmap; +int main(){ + +} \ No newline at end of file diff --git a/mana_code/global_data.h b/mana_code/global_data.h new file mode 100644 index 0000000..392ffa8 --- /dev/null +++ b/mana_code/global_data.h @@ -0,0 +1,9 @@ +//声明一个课程号和课程的映射,学号和学生的映射 +#ifndef GLOBAL_DATA_H +#define GLOBAL_DATA_H +#include +#include +#include"mana_Course.h" +// 声明(注意是 extern) +extern std::unordered_map coursemap; +#endif \ No newline at end of file diff --git a/mana_code/global_data1.h b/mana_code/global_data1.h new file mode 100644 index 0000000..77d5289 --- /dev/null +++ b/mana_code/global_data1.h @@ -0,0 +1,8 @@ +#ifndef GLOBAL_DATA1_H +#define GLOBAL_DATA1_H +#include +#include +#include "mana_Student.h" +// 声明(注意是 extern) +extern std::unordered_map studentmap; +#endif // GLOBAL_DATA1_H diff --git a/mana_code/global_data2.cpp b/mana_code/global_data2.cpp new file mode 100644 index 0000000..7eaeb48 --- /dev/null +++ b/mana_code/global_data2.cpp @@ -0,0 +1,5 @@ +#include"global_data2.h" +std::unordered_map classmap; +int main(){ + +} \ No newline at end of file diff --git a/mana_code/global_data2.h b/mana_code/global_data2.h new file mode 100644 index 0000000..e29fa10 --- /dev/null +++ b/mana_code/global_data2.h @@ -0,0 +1,9 @@ +//声明一个班级名字和班级的映射 +#ifndef GLOBAL_DATA_HH +#define GLOBAL_DATA_HH +#include +#include +#include"mana_Class.h" +// 声明(注意是 extern) +extern std::unordered_map classmap; +#endif \ No newline at end of file diff --git a/mana_code/global_data3.cpp b/mana_code/global_data3.cpp new file mode 100644 index 0000000..5da88d8 --- /dev/null +++ b/mana_code/global_data3.cpp @@ -0,0 +1,5 @@ +#include"global_data3.h" +std::unordered_map teachermap; +int main(){ + +} \ No newline at end of file diff --git a/mana_code/global_data3.h b/mana_code/global_data3.h new file mode 100644 index 0000000..96e81c6 --- /dev/null +++ b/mana_code/global_data3.h @@ -0,0 +1,5 @@ +#ifndef GLOBAL_DATAHHH +#define GLOBAL_DATAHHH +#include"mana_Teacher.h" +extern std::unordered_map teachermap; +#endif \ No newline at end of file diff --git a/mana_code/mana_Class.h b/mana_code/mana_Class.h new file mode 100644 index 0000000..e855cb5 --- /dev/null +++ b/mana_code/mana_Class.h @@ -0,0 +1,177 @@ +#ifndef MANA_CLASS +#define MANA_CLASS +#include"global_data1.h" +#include"mana_ini.h" +#include +#include +#include +#include +#include +class Clas { +private: + string className; // 班级名称 + unordered_set students; // 班级学生列表 + unordered_set mancou; // 必修课程列表 +public: + Clas() : className(""),students({""}),mancou({""}) {} + Clas(string name) : className(name) {} + //输出学生 + unordered_set getStudents() const { + return students; + } + // 添加/删除学生 + void addStudent(const string& student){ + //边界条件 + if(studentmap.find(student) == studentmap.end()) { + cout << "Student not found." << endl; + return; + } + if(!students.count(student)){ + students.insert(student); + //更新学生信息 + Student stu=studentmap[student]; + stu.setClassName(className); + //更新学生必修课 + for(const string& item : mancou){ + stu.setmancourse(item); // 设置必修课 + } + studentmap[student]=stu; // 更新学生信息 + } + } + void removeStudent(const string& student){ + //边界条件 + if(studentmap.find(student) == studentmap.end()) { + cout << "Student not found." << endl; + return; + } + if(students.count(student)) + students.erase(student); + //更新学生信息 + Student stu=studentmap[student]; + stu.setClassName(""); // 清空班级信息 + //更新学生必修课 + for(const string& item : mancou){ + stu.dropmancourse(item); // 删除必修课 + } + studentmap[student]=stu; // 更新学生信息 + } + void addMandatoryCourse(const string& course){ // 添加必修课程 + if(coursemap.find(course) == coursemap.end()) { + cout << "Course not found." << endl; + return; + } + if(!mancou.count(course)){ + mancou.insert(course); + for(const string& item : students){ + Student stu=studentmap[item]; + stu.setmancourse(course); + studentmap[item]=stu; // 更新学生信息 + } + //更新课程信息 + coursemap[course].setMandatoryForClass(className); + } + else { + cout << "This course is already mandatory for this class." << endl; + } + } + void removeMandatoryCourse(const string& course){ // 删除必修课程 + if(coursemap.find(course) == coursemap.end()) { + cout << "Course not found." << endl; + return; + } + if(mancou.count(course)) + mancou.erase(course); + for(const string& item : students){ + Student stu=studentmap[item]; + stu.dropmancourse(course); + studentmap[item]=stu; // 更新学生信息 + } + //更新课程信息 + coursemap[course].outmanclass().erase(className); + } + // 获取信息 + string getClasName() const { return className; } + // 计算班级平均分 + double calAveragegpa() const{ + double tot=0,num=0; + for(const string& item : students){ + Student stu=studentmap[item]; + num+=1; + tot+=stu.outGPA(); + } + return tot/num; + } + //按照GPA对学生进行排序 + vector> sortstu() const{ + vector> stulist; + for(const string& item : students){ + pair stunow; + Student stu=studentmap[item]; + stunow.first=stu.getStudentId(); + stunow.second=stu.outGPA(); + stulist.push_back(stunow); + } + sort(stulist.begin(), stulist.end(), [](const pair& a, const pair& b) { + return a.second < b.second; + }); + return stulist; + } + //输出学和班级的端口 + unordered_set getstu() const { + return students; + } + void outstu(){ + for(const string& item : students){ + cout << item << " "; + } + cout << endl; + } + unordered_set getcou() const { + return mancou; + } + //得到所有老师教的课程成绩 + indexoutD get_all_cou_grade(const string &teacherId,bool ifall) const { + unordered_map> grade_data; + unordered_map> second_idx; + vector first_idx; + indexoutD allGrades; + for(const string& coursename : mancou) { + Course course = coursemap[coursename]; + if (ifall || course.getAssignedTeacher() == teacherId) { + for (const string& studentId : students) { + double grade = studentmap[studentId].courseGrades[coursename]; + grade_data[coursename][studentId] = grade; + second_idx[coursename].push_back(studentId); + } + first_idx.push_back(coursename); + } + } + allGrades.first_idx = first_idx; + allGrades.second_idx = second_idx; + allGrades.data = grade_data; + return allGrades; + } + // 得到所有课程成绩(包含选修课程) + indexoutD inquiremanselcougrade(){ + unordered_map> grade_data; + unordered_map> second_idx; + vector first_idx; + indexoutD allGrades; + for(const string & studentid : students) { + Student stu = studentmap[studentid]; + for(const string& coursename : stu.mancourses) { + double grade = stu.courseGrades[coursename]; + grade_data[coursename][studentid] = grade; + second_idx[coursename].push_back(studentid); + if (find(first_idx.begin(), first_idx.end(), coursename) == first_idx.end()) { + first_idx.push_back(coursename); + } + } + } + allGrades.first_idx = first_idx; + allGrades.second_idx = second_idx; + allGrades.data = grade_data; + return allGrades; + } +}; +#endif \ No newline at end of file diff --git a/mana_code/mana_Course.h b/mana_code/mana_Course.h new file mode 100644 index 0000000..6e09a66 --- /dev/null +++ b/mana_code/mana_Course.h @@ -0,0 +1,74 @@ +#ifndef MANA_BASE_COURSE +#define MANA_BASE_COURSE +#include +#include +#include +#include +using namespace std; +class Course { + private: + string courseId; + string courseName; + bool isElective; + int dday,st,ed,val; + unordered_set mandatoryForClasses; // 必修此课的班级 + unordered_set selectstu; //修这个课的学生 + string teacher; +public: + Course() : + courseId(""), courseName(""), isElective(0), dday(0) ,st(0),ed(0),val(0),mandatoryForClasses({""}),selectstu({""}),teacher(""){} + Course(string id, string name, bool isElective,int dayy,int stt,int edd,int val) + : courseId(id), courseName(name), isElective(isElective),dday(dayy),st(stt),ed(edd),val(val) {} + // 设置课程为某个班级的必修课 + void setMandatoryForClass(const string& classnumber) { + if (mandatoryForClasses.count(classnumber)) { + cout << "This class is already mandatory for this course." << endl; + return; + } + mandatoryForClasses.insert(classnumber); + } + void eraseMandatoryForClass(const string& classnumber) { + if (!mandatoryForClasses.count(classnumber)) { + cout << "This class is not mandatory for this course." << endl; + return; + } + mandatoryForClasses.erase(classnumber); + } + // 设置课程时间表 + void setSchedule(int day, int start, int end) { + dday = day; + st = start; + ed = end; + } + //改变课程的选修状态 + void setElective(bool elective) { + isElective = elective; + } + void stu_select(const string& stu_number){ + selectstu.insert(stu_number); + } + // 检查是否为某班级的必修课 + bool isMandatoryForClass(const string& classnumber) const { + return mandatoryForClasses.count(classnumber); + } + // 分配授课教师 + void assign_teach(const string &teach){ + teacher=teach; + } + string getCourseId() const { return courseId; } + string getCourseName() const { return courseName; } + bool getIsElective() const { return isElective; } + string getAssignedTeacher() const { return teacher; } + int getst() const{ return st; } + int geted() const { return ed; } + int getval() const { return val; } + int getday() const { return dday; } + unordered_set outstu() const { + return selectstu; + } + unordered_set outmanclass() const{ + return mandatoryForClasses; + } +}; + +#endif // MANA_BASE_COURSE diff --git a/mana_code/mana_Person.h b/mana_code/mana_Person.h new file mode 100644 index 0000000..6e9461b --- /dev/null +++ b/mana_code/mana_Person.h @@ -0,0 +1,26 @@ +#ifndef MANA_PERSON_H +#define MANA_PERSON_H +#include +using namespace std; +class Person { +public: + Person(string name, string gender) + : name(name), gender(gender) {} + + virtual ~Person() {} + + string getName() const { return name; } + string getGender() const { return gender; } + void setName(const string& name) { this->name = name; } + void setGender(const string &newgender) { + if (newgender == "男" || newgender == "女") { + gender = newgender; + } else { + cout << "性别输入不合法,请重新输入。" << endl; + } + } +protected: + string name; + string gender; +}; +#endif diff --git a/mana_code/mana_Student.h b/mana_code/mana_Student.h new file mode 100644 index 0000000..6cf1e6a --- /dev/null +++ b/mana_code/mana_Student.h @@ -0,0 +1,230 @@ +#ifndef mana_Student +#define mana_Student +#include +#include +#include +#include +#include +#include"mana_Course.h" +#include"mana_Person.h" +#include"global_data.h" +#include"mana_ini.h" +#include +using namespace std; +class Student : public Person { +protected: + string studentId; + string className; // 已选选修课课程 + double gpa; +public: + Student() : Person("", ""), studentId(""), className(""), gpa(0) {} + Student(string id, string name, + string gender, string className) + : Person(name, gender), studentId(id), className(className) {} + unordered_set selectedCourses; + unordered_set mancourses; + map courseGrades; + //设置班级 + void setClassName(const string& className) { + this->className = className; + } + void selectCourse(const string& coursenumber){ //选课只能选选修课 + if(coursemap.find(coursenumber) == coursemap.end()) { + cout << "课程不存在,无法选课。" << endl; + return; + } + if(!coursemap[coursenumber].getIsElective()) { + cout << "只能选修选修课,无法选必修课。" << endl; + return; + } + if(!selectedCourses.count(coursenumber)){ + selectedCourses.insert(coursenumber); + coursemap[coursenumber].stu_select(studentId); // 将学生添加到课程的选修学生列表中 + cout<< "选课成功!" << endl; + if(courseGrades.find(coursenumber) == courseGrades.end()) { + courseGrades[coursenumber] = 0; // 初始化成绩为0 + } + } + } + void dropCourse(const string& course){ //退课 + if(coursemap.find(course) == coursemap.end()) { + cout << "课程不存在,无法退课。" << endl; + return; + } + if(!coursemap[course].getIsElective()) { + cout << "只能退选修课,无法退必修课。" << endl; + return; + } + if(selectedCourses.count(course)){ + selectedCourses.erase(course); + coursemap[course].outstu().erase(studentId); // 从课程的选修学生列表中移除 + courseGrades.erase(course); // 删除成绩记录 + cout<< "退课成功!" << endl; + } + } + void setmancourse(const string& course){ //设置必修课 + if(coursemap.find(course) == coursemap.end()) { + cout << "课程不存在,无法设置为必修课。" << endl; + return; + } + if(!mancourses.count(course)){ + mancourses.insert(course); + if(courseGrades.find(course) == courseGrades.end()) { + courseGrades[course] = 0; // 初始化成绩为0 + } + } + } + void dropmancourse(const string& course){ //删除必修课 + if(coursemap.find(course) == coursemap.end()) { + cout << "课程不存在,无法删除必修课。" << endl; + return; + } + if(mancourses.count(course)) { + mancourses.erase(course); + courseGrades.erase(course); // 删除成绩记录 + } + } + //设置成绩 + void setGrade(const string& course, double grade){ + if(mancourses.find(course) == mancourses.end() && selectedCourses.find(course) == selectedCourses.end()) { + cout << "课程不存在于该学生的课程表,无法设置成绩。" << endl; + return; + } + courseGrades[course]=grade; + cout<< "成绩已设置为 " << grade << endl; + } + // 计算GPA + void getGPA(){ + double totnum=0,totval=0; + for(const string& item : mancourses){ + totnum+=courseGrades[item]*coursemap[item].getval(); + totval+=coursemap[item].getval(); + } + if(totval==0) { + cout << "没有成绩记录,无法计算 GPA" << endl; + return; + } + gpa=totnum/(totval*25); + } + double outGPA(){ + getGPA(); // 确保 GPA 已经计算 + return gpa; + } + string getStudentId() const { return studentId; } + string getClassName() const { return className; } + void print_grade(){ + double totnum=0,totval=0; + for(const string& item : mancourses){ + Course coursenow = coursemap[item]; + cout<> check_time; + unordered_map> res1; //存储课表 + unordered_map> res2; //第二维的顺序向量 + vector res; //存储星期的顺序(第一维顺序向量) + for (int i = 1; i <= 7; i++) + for (int j = 1; j <= 11; j++) + check_time[i][j] = "NULL"; + for (const string& item : selectedCourses) { + Course coursenow = coursemap[item]; + int daynow = coursenow.getday(); + int stnow = coursenow.getst(); + int ednow = coursenow.geted(); + for (int i = stnow; i <= ednow; i++) { + if (daynow < 1 || daynow > 7 || i < 1 || i > 11) { + cout << "课程时间设置错误,无法添加到课表。" << endl; + return ans; + } + if (check_time[daynow][i] != "NULL") { + check_time[daynow][i]= "冲突"; + } + else check_time[daynow][i] = item+"(选修课)",cout< 7 || i < 1 || i > 11) { + cout << "课程时间设置错误,无法添加到课表。" << endl; + return ans; + } + if (check_time[daynow][i] != "NULL") { + check_time[daynow][i]= "冲突"; + } + else check_time[daynow][i] = item+"(必修课)",cout< temp; + for (int j = 1; j <= 11; j++) { + string timenow = "第" + to_string(j) + "节"; + temp.push_back(timenow); + if (check_time[i][j] == "NULL") { + res1[daynow][timenow] = "无课"; + } else if (check_time[i][j] == "冲突") { + res1[daynow][timenow] = "冲突"; + } else { + res1[daynow][timenow] = check_time[i][j]; + } + } + res2[daynow] = temp; + res.push_back(daynow); + } + ans.first_idx = res; + ans.second_idx = res2; + ans.data = res1; + return ans; + } + // 打印课表 + void printTimetable() { + indexoutS timetable = getTimetable(); + string filename= substring(studentId, 1, studentId.size()) +Person::getName()+ ".ini"; // 假设文件名为学号加上.ini后缀 + writeIniFromMapS(filename, timetable); + cout << "学生 " << getName() << " 的课表已写入 " << filename << " 文件。" << endl; + } + // 输出必修课 + void printMandatoryCourses() const { + cout << "必修课列表:" << endl; + for (const string& course : mancourses) { + cout << course << endl; + } + } + // 修改信息 + void modifyInfo(const string &newid, const string &newname, const string &newgender, const string &newclass) { + if (newid.empty() || newname.empty() || newgender.empty() || newclass.empty()) { + cout << "信息不能为空,请重新输入。" << endl; + return; + } + for(const string& item : selectedCourses) { // 更新选修课程的学号 + coursemap[item].outstu().erase(studentId); // 从课程的选修学生列表中移除 + coursemap[item].stu_select(newid); // 将新学号添加到课程的选修学生列表中 + } + studentId = newid; + setName(newname); + setGender(newgender); + setClassName(newclass); + } +}; +#endif \ No newline at end of file diff --git a/mana_code/mana_Teacher.h b/mana_code/mana_Teacher.h new file mode 100644 index 0000000..c045b41 --- /dev/null +++ b/mana_code/mana_Teacher.h @@ -0,0 +1,194 @@ +#ifndef MANA_TEACHER +#define MANA_TEACHER +#include +#include +#include +#include +#include"global_data.h" +#include"global_data2.h" +#include"mana_Student.h" +#include"mana_ini.h" +using namespace std; + +class Teacher : public Person { +private: + string teacherId; + unordered_set assignedCourses; // 负责的课程 + bool chongtu; +public: + Teacher() : Person("", ""), teacherId(""), chongtu(false) {} + // 构造函数 + Teacher(string id, string name, + string gender) + : Person(name, gender), teacherId(id) {} + // 获取教师ID + string getTeacherId() const { return teacherId; } + // 课程管理 + void assignCourse(const string& course){ + if(!assignedCourses.count(course)){ + assignedCourses.insert(course); + coursemap[course].assign_teach(teacherId); + } + else { + cout << "This course is already assigned to this teacher." << endl; + } + } + void removeCourse(const string& course){ + if(assignedCourses.count(course)) { + assignedCourses.erase(course); + coursemap[course].assign_teach(""); + } + else { + cout << "This course is not assigned to this teacher." << endl; + } + } + //在读入班级的成绩表时采用文件读入的方法 + void teacherreadCourseGrades(const string& courseId) { + unordered_map grades = readCourseGrades(courseId); + if (grades.empty()) { + cout << "没有找到课程 " << courseId << " 的成绩数据。" << endl; + return; + } + setGradeForCourses(courseId, grades); + } + // 获取已分配的课程 + unordered_set getAssignedCourses() const { + return assignedCourses; + } + // 设置单个学生的成绩 + void setGradeForStudent(const string& course, const string& studentId, double grade) { + if (assignedCourses.count(course) == 0) { + cout << "该课程未分配给此教师,无法设置成绩。" << endl; + return; + } + if (studentmap.find(studentId) == studentmap.end()) { + cout << "学生不存在,无法设置成绩。" << endl; + return; + } + Course coursenow = coursemap[course]; + Student& student = studentmap[studentId]; + student.setGrade(course, grade); + studentmap[studentId] = student; // 更新学生信息 + } + bool checkScheduleConflict() { //判断课表是否冲突 + bool busy[8][12]; + for(int i=1;i<=7;i++) + for(int j=1;j<=11;j++) + busy[i][j]=0; + for(const string& item : assignedCourses){ + Course coursenow=coursemap[item]; + int st=coursenow.getst(),ed=coursenow.geted(),daynow=coursenow.getday(); + if(st<=11&&st>=1&&ed<=11&&ed>=1&&daynow>=1&&daynow<=11) + for(int i=st;i<=ed;i++){ + if(busy[daynow][i]) return 1; + else busy[daynow][i]=1; + } + } + return 0; + } + // 数字与每周的对应关系 + // 设置成绩 + void setGradeForCourses(const string& course, const unordered_map& grades){ + Course coursenow=coursemap[course]; + unordered_set stu2=coursenow.outstu(); // 获取选修该课程的学生 + unordered_set man2=coursenow.outmanclass(); // 获取必修该课程的班级 + // 更新选修课程的学生成绩 + for(const string & item : stu2){ + if(grades.count(item)) { + studentmap[item].setGrade(course, grades.at(item)); + cout< stunow=classmap[item].getStudents(); // 获取该班级的学生 + for(const string & stu : stunow){ + if(grades.count(stu)) { + studentmap[stu].setGrade(course, grades.at(stu)); + cout<> check_time; + unordered_map> res1; //存储课表 + unordered_map> res2; //第二维的顺序向量 + vector res; //存储星期的顺序(第一维顺序向量) + indexoutS ans; // 返回的课表结构 + for(int i=1;i<=7;i++) + for(int j=1;j<=11;j++) + check_time[i][j]="NULL"; + for(const string& item : assignedCourses){ + Course coursenow=coursemap[item]; + int st=coursenow.getst(),ed=coursenow.geted(),daynow=coursenow.getday(); + if(st>11 || st<1 || ed>11 || ed<1 || daynow<1 || daynow>7) { + cout << "课程时间设置错误,请检查课程 " << coursenow.getCourseName() << " 的时间设置。" << endl; + continue; + } + for(int i=st;i<=ed;i++){ + if(check_time[daynow][i] != "NULL") { + check_time[daynow][i] == " 冲突 "; + chongtu = true; + } + else check_time[daynow][i]= coursenow.getCourseName(); + } + } + for(int i=1;i<=7;i++){ + string daynow= getDayName(i); + vector temp; + for(int j=1;j<=11;j++){ + string timenow="第"+to_string(j)+"节"; + temp.push_back(timenow); + if(check_time[i][j] == "NULL") { + res1[daynow][timenow]=" 无课 "; + } else if(check_time[i][j] == " 冲突 ") { + res1[daynow][timenow]=" 冲突 "; + } else { + res1[daynow][timenow]=check_time[i][j]; + } + } + res2[daynow]=temp; + res.push_back(daynow); + } + ans.first_idx=res; + ans.second_idx=res2; + ans.data=res1; + return ans; + } + //输出姓名 + string getName() const { + return Person::getName(); + } + //打印课表 + void printTimetable() { + indexoutS timetable = getTimetable(); + string filename; + filename= substring(teacherId, 1, teacherId.size()) +getName()+ ".ini"; // 假设文件名为教师ID加上.ini后缀 + writeIniFromMapS(filename, timetable); + cout << "教师 " << getName() << " 的课表已写入 " << filename << " 文件。" << endl; + chongtu=checkScheduleConflict(); + if(chongtu) cout<<"有冲突的课程,请检查!"<getStudentId(); + if (studentmap.find(stuname) != studentmap.end()) { + cout << "Student already exists." << endl; + return; + } + if (classmap.find(student->getClassName()) == classmap.end()) { + cout << "Class not found." << endl; + return; + } + studentmap[stuname] = *student; // 添加学生到学生映射 + classmap[student->getClassName()].addStudent(stuname); // 将学生添加到班级 + // 初始化学生必修课成绩为0 + for (const auto& course : classmap[student->getClassName()].getcou()) { + student->setmancourse(course); // 设置必修课 + student->setGrade(course, 0); // 设置必修课成绩为0 + } + studentmap[stuname] = *student; // 添加学生到学生映射 + } + void removeStudent(const string& student){ + if (studentmap.find(student) == studentmap.end()) { + cout << "Student not found." << endl; + return; + } + classmap[studentmap[student].getClassName()].removeStudent(student); // 从班级中移除学生 + studentmap.erase(student); // 从学生映射中删除学生 + cout << "Student " << student << " has been removed." << endl; + } + // 修改学生信息 + void modifyStudent(const string& studentId, const string& newName, const string& newGender, const string& newClassName) { + if (studentmap.find(studentId) == studentmap.end()) { + cout << "Student not found." << endl; + return; + } + Student& student = studentmap[studentId]; + student.setName(newName); + student.setGender(newGender); + studentmap[studentId] = student; // 更新学生信息 + if (classmap.find(newClassName) == classmap.end()) { + cout << "Class not found." << endl; + return; + } + // 如果班级发生变化,先从原班级中移除学生 + if (student.getClassName() != newClassName) { + classmap[student.getClassName()].removeStudent(studentId); + classmap[newClassName].addStudent(studentId); // 将学生添加到新班级 + } + cout<< "Student " << studentId << " has been modified." << endl; + } + // 修改教师信息 + void modifyTeacher(const string& teacherId, const string& newName, const string& newGender) { + if (teachermap.find(teacherId) == teachermap.end()) { + cout << "Teacher not found." << endl; + return; + } + Teacher& teacher = teachermap[teacherId]; + teacher.setName(newName); + teacher.setGender(newGender); + teachermap[teacherId] = teacher; // 更新教师信息 + cout << "Teacher " << teacherId << " has been modified." << endl; + } + void addTeacher(Teacher* teacher){ + if (teachermap.find(teacher->getTeacherId()) != teachermap.end()) { + cout << "Teacher already exists." << endl; + return; + } + string teachername=teacher->getTeacherId(); + teachermap[teachername]=*teacher; + } + void removeTeacher(const string& teacher){ + if (teachermap.find(teacher) == teachermap.end()) { + cout << "Teacher not found." << endl; + return; + } + for (const auto& course : teachermap[teacher].getAssignedCourses()) { + coursemap[course].assign_teach(""); // 清除课程的授课教师 + } + teachermap.erase(teacher); + cout<< "Teacher " << teacher << " has been removed." << endl; + } + void addCourse(Course* course){ + if(coursemap.find(course->getCourseId()) != coursemap.end()) { + cout << "Course already exists." << endl; + return; + } + string coursename=course->getCourseId(); + coursemap[coursename]=*course; + } + void setCourseMandatory(const string &course, const string& className){ + if (coursemap.find(course) != coursemap.end()&& classmap.find(className) != classmap.end()) { + classmap[className].addMandatoryCourse(course); + + } else { + cout << "Course or Class not found." << endl; + } + } + void assignCourseToTeacher(const string& course,const string& teacher){ + if (coursemap.find(course) != coursemap.end() && teachermap.find(teacher) != teachermap.end()) { + teachermap[teacher].assignCourse(course); + } else { + cout << "Course or Teacher not found." << endl; + } + } + + // 排课功能 + void scheduleCourseTime(const string &course, int date,int st,int ed){ + if (coursemap.find(course) != coursemap.end()) { + coursemap[course].setSchedule(date, st, ed); + } else { + cout << "Course not found." << endl; + } + } + // 成绩管理 + void printClassGrades(const string& className){ + if (classmap.find(className) != classmap.end()) { + string filename=substring(className,1, className.size()); + filename += ".ini"; + writeIniFromMapD(filename, classmap[className].get_all_cou_grade("all",1)); + cout << "Class grades for " << className << " have been written to " << filename << "." << endl; + } else { + cout << "Class not found." << endl; + } + } + void sortClassesByAverage() { + vector> classAverages; + for (const auto& entry : classmap) { + const string& className = entry.first; + const Clas& clas = entry.second; + double averageGPA = clas.calAveragegpa(); + classAverages.emplace_back(className, averageGPA); + } + sort(classAverages.begin(), classAverages.end(), [](const pair& a, const pair& b) { + return a.second > b.second; + }); + cout << "Classes sorted by average GPA:" << endl; + for (const auto& item : classAverages) { + cout << item.first << ": " << fixed << setprecision(2) << item.second <<"/4.00"<< endl; + } + } + //增加班级 + void addClass(const string& className) { + if (classmap.find(className) == classmap.end()) { + classmap[className] = Clas(className); + } else { + cout << "Class " << className << " already exists." << endl; + } + } + //查询班级所有成绩,包含选修课 + void inquireClassAllGrades(const string& className) { + if (classmap.find(className) != classmap.end()) { + indexoutD allGrades = classmap[className].inquiremanselcougrade(); + writeIniFromMapD(className + "_all_grades.ini", allGrades); + cout << "班级 " << className << " 的所有成绩已写入文件 " << className + "_all_grades.ini" << endl; + } else { + cout << "班级不存在,请重新输入。" << endl; + } + } +}; +#endif \ No newline at end of file diff --git a/mana_code/mana_ini.h b/mana_code/mana_ini.h new file mode 100644 index 0000000..b63218e --- /dev/null +++ b/mana_code/mana_ini.h @@ -0,0 +1,114 @@ +#ifndef INI_UTIL_H +#define INI_UTIL_H +#include +#include +#include +#include +#include +#include +#include +using namespace std; +struct indexoutD { // 用于存储double类型数据的结构 + vector first_idx; // 第一维的顺序向量 + unordered_map> second_idx; // 第二维的顺序向量 + unordered_map> data; // 存储数据 +}; +struct indexoutS { // 用于存储string类型数据的结构 + vector first_idx; // 第一维的顺序向量 + unordered_map> second_idx; // 第二维的顺序向量 + unordered_map> data; // 存储数据 +}; +string substring(const string& str, int start, int end) { + if (start < 0 || end > str.size() || start >= end) { + return ""; + } + return str.substr(start, end - start); + +} +string getDayName(int day) { + switch(day) { + case 1: return "星期一"; + case 2: return "星期二"; + case 3: return "星期三"; + case 4: return "星期四"; + case 5: return "星期五"; + case 6: return "星期六"; + case 7: return "星期日"; + default: return "未知"; + } +} + unordered_map readCourseGrades(const string& courseId) { // 读取课程成绩表,文件名没有前缀,输入时需要前缀 + string filename=courseId+ ".ini"; // 假设文件名为课程ID加上.ini后缀 + unordered_map grades; + ifstream fin(filename); + if (!fin.is_open()) { + cerr << "无法打开文件: " << filename << endl; + return grades; + } + else { + cout << "成功打开文件: " << filename << endl; + } + string line; + while (getline(fin, line)) { + if (line.empty() || line[0] == ';' || line[0] == '[') continue; + size_t pos = line.find('='); + if (pos == string::npos) continue; + string studentId = line.substr(0, pos); + string gradeStr = line.substr(pos + 1); + try { + double grade = stod(gradeStr); + grades[studentId] = grade; + } catch (...) { + // 非法数据,跳过 + } + } + fin.close(); + return grades; + } +inline void writeIniFromMapD(const string& filename, indexoutD outdata) { //写入double + if (filename.empty()) { + cerr << "文件名不能为空" << endl; + return; + } + ofstream fout(filename); + if (!fout.is_open()) { + cerr << "无法写入文件: " << filename << endl; + return; + } + for (const auto& section : outdata.first_idx) { + fout << "[" << section << "]" << endl; + const auto& secondMap = outdata.second_idx[section]; + for (const auto& key : secondMap) { + fout << key << "="; + double value = outdata.data.at(section).at(key); + fout << fixed << setprecision(2) << value; // 保留两位小数 + fout << endl; + } + fout << endl; + } + fout.close(); +} +inline void writeIniFromMapS(const string& filename, indexoutS outdata) { //写入string + if (filename.empty()) { + cerr << "文件名不能为空" << endl; + return; + } + ofstream fout(filename); + if (!fout.is_open()) { + cerr << "无法写入文件: " << filename << endl; + return; + } + for(const auto& section : outdata.first_idx) { + fout << "[" << section << "]" << endl; + const auto& secondMap = outdata.second_idx[section]; + for (const auto& key : secondMap) { + fout << key << "="; + string value = outdata.data.at(section).at(key); + fout << value; // 直接写入字符串 + fout << endl; + } + fout << endl; + } + fout.close(); +} +#endif // INI_UTIL_H \ No newline at end of file