- 问题描述
学生信息包括:学号、姓名、性别、年龄、班级等信息。
小学生除了包括学生所有信息外,还包括英语、数学和语文成绩。中学生除了包括小学生所有信息外,还包括地理、历史成绩。
大学生除了包括学生所有信息外,还包括专业、英语、程序设计和高等数学等课程。设计一程序能够对学生成绩进行管理,应用到继承、抽象类、虚函数、虚基类、多态和文件的输入/输出等内容。
- 功能要求
(1)添加功能:程序能够添加不同学生的记录,提供选择界面供用户选择所要添加的类别,要求学号要唯一,如果添加了重复学号的记录时,则提示数据添加重复并取消添加。
(2)查询功能:可根据学号、姓名等信息对已添加的学生记录进行查询,如果未找到,给出相应的提示信息,如果找到,则显示相应的记录信息。
(3)显示功能:可显示当前系统中所有学生的记录,每条记录占据一行。
(4)编辑功能:可根据查询结果对相应的记录进行修改,修改时注意学号的唯一性。
(5)删除功能:主要实现对已添加的学生记录进行删除。如果当前系统中没有相应的记录,则提示“记录为空!”并返回操作。
(6)统计功能:能根据多种参数进行统计。能统计学生人数、总分、单科的平均分等。
(7)保存功能:可将当前系统中各类记录存入文件中,存入方式任意。
(8)读取功能:可将保存在文件中的信息读入到当前系统中,供用户进行使用。
(9)排序功能:可按总分和单科成绩排名次。
- 问题的解决方案
根据系统功能要求,可以将问题解决分为以下步骤:
(1)应用系统分析,建立该系统的功能模块框图以及界面的组织和设计;
(2)分析系统中的各个实体及它们之间的关系;
(3)根据问题描述,设计系统的类层次;
(4)完成类层次中各个类的描述;
(5)完成类中各个成员函数的定义;
(6)完成系统的应用模块;
(7)功能调试;
(8)完成系统总结报告。
- 思路介绍:
根据问题描述的功能要求,我们可以设计一个学生成绩管理系统。下面是该系统的解决方案及代码思路:
1. 创建基类(BaseClass):包含学号(id)、姓名(name)、性别(gender)、年龄(age)和班级(class)等基本信息。
2. 创建派生类:
- 小学生(PrimaryStudent):继承自基类,额外包括英语成绩(englishScore)、数学成绩(mathScore)和语文成绩(chineseScore)。
- 中学生(MiddleStudent):继承自小学生类,额外包括地理成绩(geographyScore)和历史成绩(historyScore)。
- 大学生(CollegeStudent):继承自基类,额外包括专业(major)、英语成绩(englishScore)、程序设计成绩(programmingScore)和高等数学成绩(mathScore)。3. 实现添加功能:
- 提供选择界面,让用户选择要添加的学生类别(小学生、中学生、大学生)。
- 用户输入学生信息并检查学号是否唯一。
- 根据选择的类别创建对应的学生对象,并将学生对象添加到系统中的学生记录列表。4. 实现查询功能:
- 提供界面让用户选择查询条件(学号、姓名等)。
- 根据用户选择的条件从学生记录列表中查找匹配的学生对象。
- 如果找到匹配的学生对象,显示相应的记录信息;如果未找到,给出提示信息。5. 实现显示功能:
- 遍历学生记录列表,逐个显示学生对象的信息。6. 实现编辑功能:
- 提供界面让用户选择要编辑的学生记录(可以根据查询结果选择)。
- 用户修改学生信息,注意学号的唯一性检查。7. 实现删除功能:
- 提供界面让用户选择要删除的学生记录(可以根据查询结果选择)。
- 从学生记录列表中删除选定的学生对象。8. 实现统计功能:
- 统计学生人数:计算学生记录列表的长度。
- 统计总分:遍历学生记录列表,累加各个学生对象的成绩。
- 统计单科平均分:遍历学生记录列表,根据类别判断所需计算的科目,并计算平均分。9. 实现保存和读取功能:
- 将学生记录列表存储到文件中,可以使用任意的存储方式(如文本文件、二进制文件等)。
- 从文件中读取保存的学生记录信息,重新构建学生记录列表。10. 实现排序功能:
- 按照总分排序:对学生记录列表进行排序,可以使用快速排序、冒泡排序等算法。
- 按照单科成绩排序:根据类别判断所需排序的科目,对学生记录列表进行排序。通过以上步骤,可以设计出一个能够对学生成绩进行管理的程序。
#include<iostream> #include<fstream> #include<vector> using namespace std; class Student { protected: string studentNumber; string name; string gender; int age; string className; public: Student(string studentNumber, string name, string gender, int age, string className) : studentNumber(studentNumber), name(name), gender(gender), age(age), className(className) {} void display() { cout << "Student Number: " << studentNumber << endl; cout << "Name: " << name << endl; cout << "Gender: " << gender << endl; cout << "Age: " << age << endl; cout << "Class: " << className << endl; } string getStudentNumber() { return studentNumber; } }; class ElementaryStudent : public Student { private: int englishGrade; int mathGrade; int chineseGrade; public: ElementaryStudent(string studentNumber, string name, string gender, int age, string className, int englishGrade, int mathGrade, int chineseGrade) : Student(studentNumber, name, gender, age, className), englishGrade(englishGrade), mathGrade(mathGrade), chineseGrade(chineseGrade) {} void display() { Student::display(); cout << "English Grade: " << englishGrade << endl; cout << "Math Grade: " << mathGrade << endl; cout << "Chinese Grade: " << chineseGrade << endl; } int calculateTotalGrade() { return englishGrade + mathGrade + chineseGrade; } }; class MiddleStudent : public ElementaryStudent { private: int geographyGrade; int historyGrade; public: MiddleStudent(string studentNumber, string name, string gender, int age, string className, int englishGrade, int mathGrade, int chineseGrade, int geographyGrade, int historyGrade) : ElementaryStudent(studentNumber, name, gender, age, className, englishGrade, mathGrade, chineseGrade), geographyGrade(geographyGrade), historyGrade(historyGrade) {} void display() { ElementaryStudent::display(); cout << "Geography Grade: " << geographyGrade << endl; cout << "History Grade: " << historyGrade << endl; } int calculateTotalGrade() { return ElementaryStudent::calculateTotalGrade() + geographyGrade + historyGrade; } }; class CollegeStudent : public Student { private: string major; int englishGrade; int programDesignGrade; int advancedMathGrade; public: CollegeStudent(string studentNumber, string name, string gender, int age, string className, string major, int englishGrade, int programDesignGrade, int advancedMathGrade) : Student(studentNumber, name, gender, age, className), major(major), englishGrade(englishGrade), programDesignGrade(programDesignGrade), advancedMathGrade(advancedMathGrade) {} void display() { Student::display(); cout << "Major: " << major << endl; cout << "English Grade: " << englishGrade << endl; cout << "Program Design Grade: " << programDesignGrade << endl; cout << "Advanced Math Grade: " << advancedMathGrade << endl; } int calculateTotalGrade() { return englishGrade + programDesignGrade + advancedMathGrade; } }; class GradeManager { private: vector<Student*> students; public: void addStudent(Student* student) { string studentNumber = student->getStudentNumber(); for (Student* s : students) { if (s->getStudentNumber() == studentNumber) { cout << "Duplicate student number! Cancel adding." << endl; return; } } students.push_back(student); cout << "Student added successfully." << endl; } void displayAllStudents() { int count = 1; for (Student* s : students) { cout << "Student " << count++ << ":" << endl; s->display(); cout << endl; } } Student* searchStudent(string studentNumber) { for (Student* s : students) { if (s->getStudentNumber() == studentNumber) { return s; } } return nullptr; } void editStudent(string studentNumber) { Student* student = searchStudent(studentNumber); if (student == nullptr) { cout << "Student not found." << endl; return; } // Edit the student's information // ... cout << "Student edited successfully." << endl; } void deleteStudent(string studentNumber) { for (auto it = students.begin(); it != students.end(); ++it) { if ((*it)->getStudentNumber() == studentNumber) { students.erase(it); cout << "Student deleted successfully." << endl; return; } } cout << "No matching student found." << endl; } int calculateTotalStudents() { return students.size(); } int calculateTotalGrade() { int totalGrade = 0; for (Student* s : students) { totalGrade += s->calculateTotalGrade(); } return totalGrade; } double calculateAverageGrade() { int totalGrade = calculateTotalGrade(); int totalStudents = calculateTotalStudents(); if (totalStudents != 0) { return static_cast<double>(totalGrade) / totalStudents; } else { return 0; } } void saveToFile(string filename) { ofstream outFile(filename); if (outFile.is_open()) { for (Student* s : students) { // Write student information to the file outFile << s->getStudentNumber() << endl; outFile << s->name << endl; outFile << s->gender << endl; outFile << s->age << endl; outFile << s->className << endl; // Write additional information based on student type ElementaryStudent* eS = dynamic_cast<ElementaryStudent*>(s); if (eS != nullptr) { outFile << "elementary" << endl; outFile << eS->englishGrade << endl; outFile << eS->mathGrade << endl; outFile << eS->chineseGrade << endl; } MiddleStudent* mS = dynamic_cast<MiddleStudent*>(s); if (mS != nullptr) { outFile << "middle" << endl; outFile << mS->geographyGrade << endl; outFile << mS->historyGrade << endl; } CollegeStudent* cS = dynamic_cast<CollegeStudent*>(s); if (cS != nullptr) { outFile << "college" << endl; outFile << cS->major << endl; outFile << cS->englishGrade << endl; outFile << cS->programDesignGrade << endl; outFile << cS->advancedMathGrade << endl; } } outFile.close(); cout << "Data saved to file." << endl; } else { cout << "Error opening file." << endl; } } void readFromFile(string filename) { ifstream inFile(filename); if (inFile.is_open()) { students.clear(); string studentNumber, name, gender, className; int age; string type; while (!inFile.eof()) { getline(inFile, studentNumber); getline(inFile, name); getline(inFile, gender); inFile >> age; inFile.ignore(); getline(inFile, className); getline(inFile, type); if (type == "elementary") { int englishGrade, mathGrade, chineseGrade; inFile >> englishGrade >> mathGrade >> chineseGrade; inFile.ignore(); ElementaryStudent* eS = new ElementaryStudent(studentNumber, name, gender, age, className, englishGrade, mathGrade, chineseGrade); students.push_back(eS); } else if (type == "middle") { int englishGrade, mathGrade, chineseGrade, geographyGrade, historyGrade; inFile >> englishGrade >> mathGrade >> chineseGrade >> geographyGrade >> historyGrade; inFile.ignore(); MiddleStudent* mS = new MiddleStudent(studentNumber, name, gender, age, className, englishGrade, mathGrade, chineseGrade, geographyGrade, historyGrade); students.push_back(mS); } else if (type == "college") { string major; int englishGrade, programDesignGrade, advancedMathGrade; inFile >> major >> englishGrade >> programDesignGrade >> advancedMathGrade; inFile.ignore(); CollegeStudent* cS = new CollegeStudent(studentNumber, name, gender, age, className, major, englishGrade, programDesignGrade, advancedMathGrade); students.push_back(cS); } } inFile.close(); cout << "Data read from file." << endl; } else { cout << "Error opening file." << endl; } } }; int main() { GradeManager gradeManager; string filename = "students.txt"; // Add some sample students ElementaryStudent* elementary1 = new ElementaryStudent("001", "John Doe", "Male", 10, "Grade 1", 80, 90, 85); gradeManager.addStudent(elementary1); MiddleStudent* middle1 = new MiddleStudent("002", "Jane Smith", "Female", 13, "Grade 7", 75, 82, 78, 90, 85); gradeManager.addStudent(middle1); CollegeStudent* college1 = new CollegeStudent("003", "Tom Johnson", "Male", 18, "Major 1", "Computer Science", 80, 90, 85); gradeManager.addStudent(college1); int choice; do { cout << "********** Grade Management System **********" << endl; cout << "1. Add Student" << endl; cout << "2. Search Student" << endl; cout << "3. Display All Students" << endl; cout << "4. Edit Student" << endl; cout << "5. Delete Student" << endl; cout << "6. Calculate Statistics" << endl; cout << "7. Save Data to File" << endl; cout << "8. Read Data from File" << endl; cout << "9. Exit" << endl; cout << "********************************************" << endl; cout << "Enter your choice: "; cin >> choice; cin.ignore(); switch (choice) { case 1: // Add Student string studentNumber, name, gender, className, major; int age, englishGrade, mathGrade, chineseGrade, geographyGrade, historyGrade, programDesignGrade, advancedMathGrade; cout << "Enter student number: "; getline(cin, studentNumber); cout << "Enter name: "; getline(cin, name); cout << "Enter gender: "; getline(cin, gender); cout << "Enter age: "; cin >> age; cin.ignore(); cout << "Enter class name: "; getline(cin, className); cout << "*********************" << endl; cout << "Select student type:" << endl; cout << "1. Elementary Student" << endl; cout << "2. Middle Student" << endl; cout << "3. College Student" << endl; cout << "*********************" << endl; cout << "Enter your choice: "; int typeChoice; cin >> typeChoice; cin.ignore(); switch (typeChoice) { case 1: // Elementary Student cout << "Enter English Grade: "; cin >> englishGrade; cout << "Enter Math Grade: "; cin >> mathGrade; cout << "Enter Chinese Grade: "; cin >> chineseGrade; ElementaryStudent* elementary = new ElementaryStudent(studentNumber, name, gender, age, className, englishGrade, mathGrade, chineseGrade); gradeManager.addStudent(elementary); break; case 2: // Middle Student cout << "Enter English Grade: "; cin >> englishGrade; cout << "Enter Math Grade: "; cin >> mathGrade; cout << "Enter Chinese Grade: "; cin >> chineseGrade; cout << "Enter Geography Grade: "; cin >> geographyGrade; cout << "Enter History Grade: "; cin >> historyGrade; MiddleStudent* middle = new MiddleStudent(studentNumber, name, gender, age, className, englishGrade, mathGrade, chineseGrade, geographyGrade, historyGrade); gradeManager.addStudent(middle); break; case 3: // College Student cout << "Enter major: "; getline(cin, major); cout << "Enter English Grade: "; cin >> englishGrade; cout << "Enter Program Design Grade: "; cin >> programDesignGrade; cout << "Enter Advanced Math Grade: "; cin >> advancedMathGrade; CollegeStudent* college = new CollegeStudent(studentNumber, name, gender, age, className, major, englishGrade, programDesignGrade, advancedMathGrade); gradeManager.addStudent(college); break; default: cout << "Invalid choice." << endl; break; } break; case 2: // Search Student cout << "Enter student number to search: "; getline(cin, studentNumber); Student* result = gradeManager.searchStudent(studentNumber); if (result != nullptr) { result->display(); } else { cout << "Student not found." << endl; } break; case 3: // Display All Students gradeManager.displayAllStudents(); break; case 4: // Edit Student cout << "Enter student number to edit: "; getline(cin, studentNumber); gradeManager.editStudent(studentNumber); break; case 5: // Delete Student cout << "Enter student number to delete: "; getline(cin, studentNumber); gradeManager.deleteStudent(studentNumber); break; case 6: // Calculate Statistics cout << "Total students: " << gradeManager.calculateTotalStudents() << endl; cout << "Total grade: " << gradeManager.calculateTotalGrade() << endl; cout << "Average grade: " << gradeManager.calculateAverageGrade() << endl; break; case 7: // Save Data to File gradeManager.saveToFile(filename); break; case 8: // Read Data from File gradeManager.readFromFile(filename); break; case 9: // Exit cout << "Exiting program..." << endl; break; default: cout << "Invalid choice." << endl; break; } cout << endl; } while (choice != 9); return 0; }