問題描述
實現學生成績管理系統:
學生信息包括:學號、姓名、性別、年齡、班級等信息。除了包括學生所有信息外,還包括專業、英語、程序設計和高等數學等課程。 設計一程序能夠對學生成績進行管理,應用到繼承、抽象類、虛函數、虛基類、多態和文件的輸入/輸出等內容。用戶自行輸入所需要的數據或者被要求的數據,或從“.txt”文檔中輸入輸出的形式;以文件的形式輸出程序所能達到的功能。
功能:1添加功能、2查詢功能、3顯示功能、4編輯功能、5刪除功能、6統計功能、7保存功能、8讀取功能、9排序功能
類的定義及類之間的關系
本程序一共分為四大類:Info(學生基本信息類) ?course(課程分數類) student(學生類) ?studentmanager(學生管理類)
其中Info類定義學生的基本信息:學號(id),姓名(name),性別(gender),年齡(age),班級(ClassName),course類定義學生的課程分數:專業課(zhuanye),英語課(englishscore),程序設計(programingscore),高等數學課程(mathscore)。student類繼承Info類以及course,并且新增total(總分)和average(平均分)兩個新的成員變量。其中本類還包含與用戶的交互界面display()函數。Studentmanager類為功能實現類。其中,本類創造了student類容器,以容器的方式代替對象數組的功能,包含九個功能函數。
程
程序模塊
序模塊分為三大模塊:類設計模塊,用戶界面交互模塊,函數設計模塊。
類設計模塊主要是定義學生基本信息以及分數類,在類中的構造函數中實現成員變量的復制以及與其對應的get/set方法。
用戶界面交互的模塊主要是以switch/case模塊搭建的cout/cin(輸入/輸出)體系模塊,也就是與使用用戶有關的模塊。
函數設計模塊為實現功能算法的模塊,在此模塊中,可以實現用戶的多種需求,但是原則上將其封裝起來,不對用戶暴露。此模塊一共分為11個功能函數,分別為:
void saveToFile():保存學生記錄
void loadFromFile()?:從文件中讀取學生記錄
void addStudent()???:添加學生記錄
void displayAllStudents():顯示所有學生記錄
void searchStudent()????:查找學生信息
void editStudent()??????:修改學生記錄
void deleteStudent()????:刪除學生信息
void calculateStatistics()?:統計學生成績排名
void menu() ???????????????:排序菜單
cmp函數:
static bool compareByTotalScore(Student* s1, Student* s2)
??????????static bool compareByEnglishScore(Student* s1, Student* s2)
??????????static bool compareByProgrammingScore(Student* s1, Student* s2)
??????????static bool compareByMathScore(Student* s1, Student* s2)
??????????static bool compareByzhuanyescore(Student* s1, Student* s2)
Sort函數: ?
void sortStudentsByTotalScore()
void sortStudentsByEnglishScore()
void sortStudentsByProgrammingScore()
void sortStudentsByMathScore()
void sortStudentsByzhuanyeScore()
算法設計
算法分析:本程序一共分為3大模塊,其中算法用的不算太多,也不是很難,除了排序,查找,修改之外其他基本用不上算法。
算法的實現:
基于本程序的數據保存的結構是以容器(vector)實現的,因此上,在算法實現上都是以容器(vector)的方式進行實現的,STL?對定義的通用容器分三類:順序性容器、關聯式容器和容器適配器。本程序主要是以順序性容器為基本來實現上述算法要求的。
順序性容器?是 一種各元素之間有順序關系的線性表,是一種線性結構的可序群集。順序性容器中的每個元素均有固定的位置,除非用刪除或插入的操作改變這個位置。這個位置和 元素本身無關,而和操作的時間和地點有關,順序性容器不會根據元素的特點排序而是直接保存了元素操作時的邏輯順序。比如一次性對一個順序性容器追加三 個元素,這三個元素在容器中的相對位置和追加時的邏輯次序是一致的。
源碼
下面是完整代碼
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
class Student{
public:friend void Input(Student stu[]);friend void Statistic(Student stu[]);friend void Lookup(Student stu[]);friend void Modify(Student stu[]);friend void Delete(Student stu[]);friend void Output(Student stu[]);friend void Insert(Student stu[]);friend void Sort(Student stu[]);friend void Write(Student stu[],int n);friend int Read(Student stu[]);
private:int num;char name[8];char class_0[20];float elec;float c_program;float english;float math;float media;float sport;float polity;float average;int order;
}stu[100];void Write(Student stu[], int n) {fstream myFile;myFile.open("score.txt", ios::out | ios::binary);if (!myFile) {cout << "score.txt can't open!" << endl;abort();}int count = n;myFile << count << endl<<endl;for (int i = 0; i < count; i++) {myFile << stu[i].class_0 << "\t"<< stu[i].num << "\t"<< stu[i].name << "\t"<< stu[i].elec << "\t"<< stu[i].c_program<< "\t"<< stu[i].media << "\t"<< stu[i].english << "\t"<< stu[i].math << "\t"<< stu[i].sport << "\t"<< stu[i].polity << "\t"<< stu[i].average << endl;}myFile.close();
}int Read(Student stu[]) {fstream myFile;myFile.open("score.txt", ios::in | ios::binary);if (!myFile) {cout << "score.txt can't open!" << endl;abort();}int count;myFile.seekg(0);myFile >> count;for (int i = 0; i <= count; i++) {myFile >> stu[i].class_0 >> stu[i].num >> stu[i].name >> stu[i].elec >> stu[i].c_program >> stu[i].media >> stu[i].english >> stu[i].math >> stu[i].sport >> stu[i].polity >> stu[i].average;}myFile.close();return count;
}void Input(Student stu[]) {system("cls");int i = 0;int flag;char sign = '0';cout << endl<<"======>> 請輸入學生成績 <<======"<<endl;while (sign != 'n' && sign != 'N') {cout << "班級:";cin >> stu[i].class_0;loop:cout << "學號:";cin >> stu[i].num;int c = 0;while (c < i) {c++;if (stu[i].num == stu[i - c].num) {cout << "您輸入的學號已存在!請重新輸入。" << endl;goto loop;}}cout << "姓名:";cin >> stu[i].name;do {flag = 0;cout << "電子技術成績:";cin >> stu[i].elec;if (stu[i].elec > 100 || stu[i].elec < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);do {flag = 0;cout << "C++程序設計成績:";cin >> stu[i].c_program;if (stu[i].c_program > 100 || stu[i].c_program < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);do {flag = 0;cout << "多媒體技術成績:";cin >> stu[i].media;if (stu[i].media > 100 || stu[i].media < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);do {flag = 0;cout << "大學英語成績:";cin >> stu[i].english;if (stu[i].english > 100 || stu[i].english < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);do {flag = 0;cout << "高等數學成績:";cin >> stu[i].math;if (stu[i].math > 100 || stu[i].math < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);do {flag = 0;cout << "大學體育成績:";cin >> stu[i].sport;if (stu[i].sport > 100 || stu[i].sport < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);do {flag = 0;cout << "馬克思主義基本原理成績:";cin >> stu[i].polity;if (stu[i].polity > 100 || stu[i].polity < 1) {cout << " 對不起,請輸入1-100之間的數字!!\n";}else {flag = 1;}} while (flag == 0);stu[i].average = (stu[i].elec + stu[i].c_program + stu[i].media + stu[i].english + stu[i].math +stu[i].sport + stu[i].polity) / 7;cout << " 平均分為:" << stu[i].average<<endl;cout << "======>> 提示:是否繼續寫入學生成績 ?(y/n)";cin >> sign;i++;}Write(stu, i);
}void Statistic(Student stu[]) {system("cls");int n = Read(stu);cout << endl << "======>> 輸出學生統計數據 <<======\n" << endl;cout << "---------------------------------------" << endl;cout << "班級" << "\t" << "學號" << "\t" << "姓名" << "\t" << "平均分" << endl;cout << "---------------------------------------" << endl;for (int i = 0; i < n; i++)cout << stu[i].class_0 << "\t" << stu[i].num << "\t" << stu[i].name << "\t" << stu[i].average << endl;cout << "---------------------------------------" << endl;system("pause");
}void Lookup(Student stu[]) {system("cls");int n = Read(stu);int s;int i = 0;cout << endl << "======>> 查找學生成績 <<======" << endl;cout << "請輸入要查找學生的學號:";cin >> s;while ((stu[i].num - s) != 0 && i < n)i++;if (i == n) {cout << "======>> 對不起,無法找到該學生...... <<======" << endl;}else {cout << "----------------------------" << endl;cout << "班級:" << stu[i].class_0 << endl;cout << "學號:" << stu[i].num << endl;cout << "姓名:" << stu[i].name << endl;cout << "電子技術:" << stu[i].elec << endl;cout << "C++程序設計:" << stu[i].c_program << endl;cout << "多媒體技術:" << stu[i].media << endl;cout << "大學英語:" << stu[i].english << endl;cout << "高等數學:" << stu[i].math << endl;cout << "大學體育:" << stu[i].sport << endl;cout << "馬克思主義基本原理:" << stu[i].polity << endl;cout << "平均分:" << stu[i].average << endl;}
}void Modify(Student stu[]) {system("cls");int n = Read(stu);int s;int i = 0;cout << endl << "======>> 修改學生成績 <<======" << endl;cout << "請輸入要修改成績學生的學號:";cin >> s;while ((stu[i].num - s) != 0 && i < n)i++;if (i == n) {cout << "======>> 對不起,無法找到該學生...... <<======" << endl;}else {cout << "------------------------------------------------------------------------------------" << endl;cout << "班級" << "\t" << "學號" << "\t" << "姓名" << "\t"<< "電子" << "\t" << "C++" << "\t" << "多媒體" << "\t"<< "英語" << "\t" << "數學" << "\t" << "體育" << "\t"<< "政治" << "\t" << "平均分" << endl;cout << "------------------------------------------------------------------------------------" << endl;cout << stu[i].class_0 << "\t" << stu[i].num << "\t" << stu[i].name << "\t"<< stu[i].elec << "\t" << stu[i].c_program << "\t" << stu[i].media << "\t"<< stu[i].english << "\t" << stu[i].math << "\t" << stu[i].sport << "\t"<< stu[i].polity << "\t" << stu[i].average << endl;cout << endl << "請重新輸入該學生成績: " << endl;cout << "電子技術成績:";cin >> stu[i].elec;cout << "C++成績:";cin >> stu[i].c_program;cout << "多媒體技術成績:";cin >> stu[i].media;cout << "大學英語成績:";cin >> stu[i].english;cout << "高等數學成績:";cin >> stu[i].math;cout << "大學體育成績:";cin >> stu[i].sport;cout << "馬克思主義基本原理成績:";cin >> stu[i].polity;stu[i].average = (stu[i].elec + stu[i].c_program + stu[i].media +stu[i].english + stu[i].math + stu[i].sport + stu[i].polity) / 7;cout << "平均分:" << stu[i].average << endl;char c;cout << "======>> 是否保存數據 ?(y/n)";cin >> c;if (c != 'n' && c != 'N')Write(stu, n);}
}void Delete(Student stu[]) {system("cls");int n = Read(stu);int s;int i = 0, j ;cout << endl << "======>> 刪除學生成績 <<======" << endl;cout << "請輸入要刪除的學生的學號:";cin >> s;while ((stu[i].num - s) != 0 && i < n)i++;if (i == n) {cout << "======>> 對不起,無法找到該學生...... <<======" << endl;}else {for (j = i; j < n - 1; j++) {strcpy(stu[j].class_0,stu[j + 1].class_0);stu[j].num = stu[j + 1].num;strcpy(stu[j].name, stu[j + 1].name);stu[j].elec = stu[j + 1].elec;stu[j].c_program = stu[j + 1].c_program;stu[j].media = stu[j + 1].media;stu[j].english = stu[j + 1].english;stu[j].math = stu[j + 1].math;stu[j].sport = stu[j + 1].sport;stu[j].polity = stu[j + 1].polity;stu[j].average = stu[j + 1].average;}cout << "======>> 提示:已成功刪除!" << endl;}Write(stu, n - 1);
}void Insert(Student stu[]) {system("cls");int n = Read(stu);char s='0';cout << endl << "=======>> 增加學生成績 <<========" << endl;while (s != 'n' && s != 'N') {cout << "班級:";cin >> stu[n].class_0;cout << "學號:";cin >> stu[n].num;cout << "姓名:";cin >> stu[n].name;cout << "電子技術成績:";cin >> stu[n].elec;cout << "C++成績:";cin >> stu[n].c_program;cout << "多媒體技術成績:";cin >> stu[n].media;cout << "大學英語成績:";cin >> stu[n].english;cout << "高等數學成績:";cin >> stu[n].math;cout << "大學體育成績:";cin >> stu[n].sport;cout << "馬克思主義基本原理成績:";cin >> stu[n].polity;stu[n].average = (stu[n].elec + stu[n].c_program + stu[n].media +stu[n].english + stu[n].math + stu[n].sport + stu[n].polity) / 7;cout << "平均分:" << stu[n].average << endl;n++;cout << "======>> 是否繼續插入(y/n)";cin >> s;}Write(stu, n);
}void Sort(Student stu[]) {system("cls");int i, j, k;float s;char t[20];cout << endl << "======>> 降序排列 <<======" << endl;int n = Read(stu);for (i = 0; i < n-1; i++) {for (j = 0; j < n - 1; j++) {if (stu[j].average < stu[j + 1].average) {//交換課程strcpy(t, stu[j + 1].class_0);strcpy(stu[j + 1].class_0, stu[j].class_0);strcpy(stu[j].class_0, t);//numk = stu[j + 1].num;stu[j + 1].num = stu[j].num;stu[j].num = k;//namestrcpy(t, stu[j + 1].name);strcpy(stu[j + 1].name, stu[j].name);strcpy(stu[j].name, t);//elecs = stu[j + 1].elec;stu[j + 1].elec = stu[j].elec;stu[j].elec = s;//c_programs = stu[j + 1].c_program;stu[j + 1].c_program = stu[j].c_program;stu[j].c_program = s;//medias = stu[j + 1].media;stu[j + 1].media = stu[j].media;stu[j].media = s;//englishs = stu[j + 1].english;stu[j + 1].english = stu[j].english;stu[j].english = s;//maths = stu[j + 1].math;stu[j + 1].math = stu[j].math;stu[j].math = s;//sports = stu[j + 1].sport;stu[j + 1].sport = stu[j].sport;stu[j].sport = s;//politys = stu[j + 1].polity;stu[j + 1].polity = stu[j].polity;stu[j].polity = s;//averages = stu[j + 1].average;stu[j + 1].average = stu[j].average;stu[j].average = s;}}}cout << "------------------------------------------------------------------------------------" << endl;cout << "班級" << "\t" << "學號" << "\t" << "姓名" << "\t"<< "電子" << "\t" << "C++" << "\t" << "多媒體" << "\t"<< "英語" << "\t" << "數學" << "\t" << "體育" << "\t"<< "政治" << "\t" << "平均分" << endl;cout << "------------------------------------------------------------------------------------" << endl;for (int i = 0; i < n; i++) {stu[i].order = i + 1;cout << stu[i].class_0 << "\t" << stu[i].num << "\t" << stu[i].name << "\t"<< stu[i].elec << "\t" << stu[i].c_program << "\t" << stu[i].media << "\t"<< stu[i].english << "\t" << stu[i].math << "\t" << stu[i].sport << "\t"<< stu[i].polity << "\t" << stu[i].average << endl;}Write(stu, n);
}void Output(Student stu[]) {system("cls");int n = Read(stu);cout << endl << "======>> 顯示全部學生成績 <<======" << endl;if (!stu) {cout << "沒有記錄";}else {cout << "------------------------------------------------------------------------------------" << endl;cout << "班級" << "\t" << "學號" << "\t" << "姓名" << "\t" << "電子" << "\t" << "C++" << "\t" << "多媒體" << "\t" << "英語" << "\t" << "數學" << "\t" << "體育" << "\t" << "政治" << "\t" << "平均分" << endl;cout << "------------------------------------------------------------------------------------" << endl;for (int i = 0; i < n; i++) {cout << stu[i].class_0 << "\t" << stu[i].num << "\t" << stu[i].name << "\t"<< stu[i].elec << "\t" << stu[i].c_program << "\t" << stu[i].media << "\t"<< stu[i].english << "\t" << stu[i].math << "\t" << stu[i].sport << "\t"<< stu[i].polity << "\t" << stu[i].average << endl;}cout << "------------------------------------------------------------------------------------" << endl;}
}int menu() {char c;do {system("cls");cout << "******************************************************" << endl;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 << " * 【0】退出管理系統 * " << endl;cout << "******************************************************" << endl;cout << "請選擇您的操作 (0-8):" << endl;c = getchar();} while (c < '0' || c > '8');return (c - '0');
}int main() {for (;;) {switch (menu()) {case 1:Input(stu);break;case 2:Statistic(stu);break;case 3:Lookup(stu);system("pause");break;case 4:Modify(stu);system("pause");break;case 5:Delete(stu);system("pause");break;case 6:Insert(stu);system("pause");break;case 7:Sort(stu);system("pause");break;case 8:Output(stu);system("pause");break;case 0:cout << endl << "================感謝您使用學生成績管理系統==============\n" << endl;exit(0);}}return 0;
}