班级学生成绩管理系统——C/C++实现
生活随笔
收集整理的這篇文章主要介紹了
班级学生成绩管理系统——C/C++实现
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
- 班級(jí)學(xué)生成績(jī)管理系統(tǒng)——C/C++實(shí)現(xiàn)
- 一、功能概述
- 二、功能詳細(xì)說明
- 三、代碼實(shí)現(xiàn)
- 四、總結(jié)
- 1. BUGS & QUESTIONS & ANSWERS
- 2. SUMMARY
班級(jí)學(xué)生成績(jī)管理系統(tǒng)——C/C++實(shí)現(xiàn)
- 項(xiàng)目功能基本完成,且有諸多改進(jìn),項(xiàng)目未完成的一兩個(gè)小BUG都標(biāo)注在文章末尾了,總體沒有問題。?
- 項(xiàng)目沒怎么用C++的東西,就一個(gè)string類和c++的輸入輸出,還有個(gè)new和函數(shù)傳引用。🤦🏻?♂?
- 項(xiàng)目只能算是初級(jí)初級(jí)初級(jí)程序設(shè)計(jì),沒有數(shù)據(jù)結(jié)構(gòu),沒有數(shù)據(jù)庫,沒有可視化便捷操控界面,沒有設(shè)計(jì)模式。(啥也不是😂)
- 希望能對(duì)入門程序猿們有一些幫助,一起 stronger。💪🏻
一、功能概述
使用 C 語言完成該系統(tǒng)的開發(fā),通過該系統(tǒng)可實(shí)現(xiàn)對(duì)某班級(jí)(例如 B175A5 班)學(xué)生成績(jī)信息的添加、查詢、修改、刪除、統(tǒng)計(jì)分析,以及數(shù)據(jù)保存、讀取等功能。
二、功能詳細(xì)說明
- 添加學(xué)生的成績(jī)信息到系統(tǒng)中,主要包括學(xué)號(hào)、姓名、各科成績(jī)。其中,學(xué)號(hào)的格式是:“班號(hào)+2 位數(shù)字”;成績(jī)要求在 0~100 之間。若輸入數(shù)據(jù)違法,則進(jìn)行相應(yīng)提
示。 - 判斷輸入的學(xué)號(hào)是否存在,若不存在,則添加到系統(tǒng);否則,提示學(xué)號(hào)已存在,不
進(jìn)行添加。 - 添加完成后,提示是否繼續(xù)添加。如果不繼續(xù)添加,則返回主菜單。
- 系統(tǒng)提供三種查詢方式,按學(xué)號(hào),按姓名,以及顯示所有學(xué)生成績(jī)信息。
- 如果查找成功,顯示該學(xué)生的成績(jī)信息;否則,提示未找到。
- 系統(tǒng)提供兩種方式進(jìn)行修改,可按姓名或?qū)W號(hào)來進(jìn)行。
- 修改時(shí),先按照提供的信息進(jìn)行查找,若查找成功,則可輸入該學(xué)生新的成績(jī)信息;否則,提示該學(xué)生不存在。
- 系統(tǒng)只提供按照學(xué)生的學(xué)號(hào)進(jìn)行刪除。
- 刪除時(shí),首先輸入學(xué)生的學(xué)號(hào),若查找到該生的信息,則將其從系統(tǒng)中刪除;否則,提示提示該學(xué)生不存在。
- 系統(tǒng)提供了選擇成績(jī)統(tǒng)計(jì)和成績(jī)排名兩種操作。
- 選擇成績(jī)統(tǒng)計(jì)時(shí),先提示對(duì)哪門課(英語、數(shù)學(xué)、計(jì)算機(jī))進(jìn)行統(tǒng)計(jì),然后提示統(tǒng)計(jì)方式。可統(tǒng)計(jì)最高分、最低分、平均分、排名、不及格的人數(shù)、優(yōu)秀的人數(shù),選擇后顯示相應(yīng)的統(tǒng)計(jì)結(jié)果。
- 選擇成績(jī)排序時(shí),先提示對(duì)哪門課(英語、數(shù)學(xué)、計(jì)算機(jī))進(jìn)行成績(jī)排序,選擇后顯示相應(yīng)排序結(jié)果。
- 系統(tǒng)中所有的學(xué)生成績(jī)系統(tǒng)都以二進(jìn)制形式保存在文件中。
三、代碼實(shí)現(xiàn)
#include <iostream> using namespace std; // #include <stdlib.h>#define MAX 50 #define TEMPSIZE 100 // 從二進(jìn)制文件提取數(shù)據(jù)的中間變量 #define CODE "作者是個(gè)大帥比" // 管理員密碼/*** 1. 存儲(chǔ)結(jié)構(gòu)*/ typedef struct {// char number[100]; // 學(xué)號(hào) char類型數(shù)據(jù)只能直接輸入/用字符串函數(shù),不能賦值// char name[100]; // 姓名// char sex[10]; // 性別// enum sex {男, 女}; // 性別string number; // 學(xué)號(hào)string name; // 姓名int sex; // 性別: 1--男,2--女int age; // 年齡float score[3]; // 成績(jī) * 3 } StudentInfo; typedef struct {StudentInfo stu_array[MAX]; // 學(xué)生信息表int stu_size; // 當(dāng)前學(xué)生數(shù)量 } StudentList;/*** 2. 操作函數(shù)*/ // 顯示菜單 void ShowMenu(); // 初始化學(xué)生表 bool InitStudentList(StudentList &); // 判斷學(xué)生表是否為空 bool IsEmpty(StudentList); // 添加學(xué)生信息 bool AddStudentList(StudentList &); // 顯示學(xué)生信息 bool ShowStudentList(StudentList); // 查詢學(xué)生信息 int SearchStudentListByNumber(StudentList, string); int SearchStudentListByName(StudentList, string); bool FindStudentListByIndex(StudentList, int); void FindStudentList(StudentList); // 刪除學(xué)生信息 bool DeleteStudentListByIndex(StudentList &, int); bool DeleteStudentList(StudentList &); // 修改學(xué)生信息 bool ModifyStudentListByIndex(StudentList &, int); bool ModifyStudentList(StudentList &); // 清空學(xué)生信息 bool ClearStudentList(StudentList &); // 文件讀寫操作 bool ClearStudentInfoInTxt(); bool ReadStudentInfoFromTxt(StudentList &); bool WriteStudentListToTxt(StudentList); // 學(xué)生信息統(tǒng)計(jì) // 學(xué)生成績(jī)排名 bool SortStudentList(StudentList &); // 學(xué)生成績(jī)統(tǒng)計(jì) bool StudentInfoStatistics(StudentList); void StudentScoreStatistics(StudentList); int CountExcellentStudents(StudentList, int); int CountFlunks(StudentList, int); float FindAverageScore(StudentList, int); float FindLowestScore(StudentList, int); float FindHighestScore(StudentList, int);/*** 2.1 菜單界面*/ void ShowMenu() {cout << "***** 歡迎來到學(xué)生信息管理系統(tǒng) *****" << endl;cout << "**** 1. 添加學(xué)生信息 ****" << endl;cout << "**** 2. 顯示學(xué)生信息 ****" << endl;cout << "**** 3. 刪除學(xué)生信息 ****" << endl;cout << "**** 4. 查詢學(xué)生信息 ****" << endl;cout << "**** 5. 修改學(xué)生信息 ****" << endl;cout << "**** 6. 統(tǒng)計(jì)學(xué)生信息 ****" << endl;cout << "**** 7. 清空學(xué)生信息 ****" << endl;cout << "**** 8. 保存學(xué)生信息到文件 ****" << endl;// cout << "**** 9. 從文件讀取學(xué)生信息 ****" << endl;cout << "**** 0. 退出管理系統(tǒng) ****" << endl;cout << "************************************" << endl; }/*** 2.2 初始化學(xué)生信息*/ bool InitStudentList(StudentList &stu_list) {stu_list.stu_size = 0; // 初始化學(xué)生表長(zhǎng)度為0char option = 'n';cout << "開始初始化系統(tǒng)……\n請(qǐng)選擇是否需要從指定文件讀取歷史學(xué)生數(shù)據(jù)(y/n):";cin >> option;while (true){if (option == 'Y' || option == 'y'){ReadStudentInfoFromTxt(stu_list); // 從文件讀取學(xué)生信息break;}else if (option == 'N' || option == 'n'){cout << "歡迎回來!\n";system("pause");system("cls");break;}else{cout << "輸入錯(cuò)誤,請(qǐng)重新輸入:";cin >> option;}}return true; }// 判空 bool IsEmpty(StudentList stu_list) {if (stu_list.stu_size == 0)return true;elsereturn false; }/*** 2.3 添加學(xué)生信息*/ bool AddStudentList(StudentList &stu_list) {if (stu_list.stu_size == MAX){ // 判滿cout << "學(xué)生列表已滿,無法添加!" << endl;system("pause");system("cls");return false;}else{ // 添加具體學(xué)生信息// 學(xué)號(hào)string number;cout << "請(qǐng)輸入學(xué)號(hào):" << endl;while (true){cin >> number;if (SearchStudentListByNumber(stu_list, number) == -1 || SearchStudentListByNumber(stu_list, number) == -2){stu_list.stu_array[stu_list.stu_size].number = number;break;}elsecout << "學(xué)號(hào)重復(fù),請(qǐng)輸入新學(xué)號(hào):";}// 姓名string name;cout << "請(qǐng)輸入姓名:" << endl;cin >> name;stu_list.stu_array[stu_list.stu_size].name = name; // 利用stu_size結(jié)構(gòu)體元素,在當(dāng)前數(shù)組尾插入學(xué)生信息// 性別cout << "請(qǐng)輸入性別:" << endl;cout << "1 -- 男" << endl;cout << "2 -- 女" << endl;int sex = 0;while (true){// 簡(jiǎn)單的輸入合法性判斷cin >> sex;if (sex == 1 || sex == 2){stu_list.stu_array[stu_list.stu_size].sex = sex;break;}cout << "輸入有誤,請(qǐng)重新輸入:" << endl;}// 年齡cout << "請(qǐng)輸入年齡:" << endl;int age = 0;while (true){// 簡(jiǎn)單的輸入合法性判斷cin >> age;if (age > 0 && age < 150){stu_list.stu_array[stu_list.stu_size].age = age;break;}cout << "輸入有誤,請(qǐng)重新輸入:" << endl;}// 成績(jī)cout << "請(qǐng)輸入成績(jī):" << endl;float score = 0.0;for (int i = 0; i < 3; ++i){while (true){// 簡(jiǎn)單的輸入合法性判斷cin >> score;if (score >= 0.0 && score <= 100.0){stu_list.stu_array[stu_list.stu_size].score[i] = score;break;}cout << "輸入有誤,請(qǐng)重新輸入:" << endl;}}stu_list.stu_size++;cout << "學(xué)生信息添加成功!" << endl;system("pause");system("cls");return true;} }/*** 2.4 顯示學(xué)生信息*/ bool ShowStudentList(StudentList stu_list) {// if (stu_list.stu_size == 0)if (IsEmpty(stu_list)){cout << "學(xué)生列表目前為空!" << endl;system("pause");system("cls");return false;}else{cout << "學(xué)號(hào)\t\t"<< "姓名\t\t"<< "性別\t\t"<< "年齡\t\t"<< "成績(jī)1\t成績(jī)2\t成績(jī)3" << endl;for (int i = 0; i < stu_list.stu_size; ++i){cout << stu_list.stu_array[i].number << "\t\t";cout << stu_list.stu_array[i].name << "\t\t";cout << (stu_list.stu_array[i].sex == 1 ? "男" : "女") << "\t\t";cout << stu_list.stu_array[i].age << "\t\t";for (int j = 0; j < 3; ++j)cout << stu_list.stu_array[i].score[j] << "\t";cout << endl;}}system("pause");system("cls");return true; }/*** 2.5 查詢學(xué)生信息*/ int SearchStudentListByNumber(StudentList stu_list, string number) {if (IsEmpty(stu_list))return -2; // 列表為空返回 -2 (-2,-1,>0對(duì)應(yīng) 3 種情況,-2最小優(yōu)先級(jí)最高。)else{for (int i = 0; i < stu_list.stu_size; ++i)if (stu_list.stu_array[i].number == number)return i;return -1; // 查詢不到學(xué)生信息返回 -1} }int SearchStudentListByName(StudentList stu_list, string name) {if (IsEmpty(stu_list))return -2;else{for (int i = 0; i < stu_list.stu_size; ++i)if (stu_list.stu_array[i].name == name)return i;return -1;} }// 根據(jù)查詢到的index位序,對(duì)學(xué)生信息進(jìn)行查找 bool FindStudentListByIndex(StudentList stu_list, int index) {if (index == -2){cout << "當(dāng)前學(xué)生列表為空!" << endl;system("pause");system("cls");return false;}else if (index == -1){cout << "查無此人!" << endl;system("pause");system("cls");return false;}else{cout << "查找成功,學(xué)生信息如下:" << endl;cout << "學(xué)號(hào)\t\t"<< "姓名\t\t"<< "性別\t\t"<< "年齡\t\t"<< "成績(jī)\t\t" << endl;cout << stu_list.stu_array[index].number << "\t\t";cout << stu_list.stu_array[index].name << "\t\t";cout << (stu_list.stu_array[index].sex == 1 ? "男" : "女") << "\t\t";cout << stu_list.stu_array[index].age << "\t\t";for (int j = 0; j < 3; ++j)cout << stu_list.stu_array[index].score[j] << "\t";cout << endl;system("pause");system("cls");return true;} }// 查找學(xué)生信息總函數(shù),設(shè)計(jì)查找操作的總邏輯以及對(duì)內(nèi)部小函數(shù)進(jìn)行調(diào)用 void FindStudentList(StudentList stu_list) {// cout << "通過輸入 學(xué)生學(xué)號(hào) 查找請(qǐng)按 1,通過輸入 學(xué)生姓名 查找請(qǐng)按 2,按其他鍵取消操作:" << endl;cout << "請(qǐng)選擇操作選項(xiàng):\n1. 通過學(xué)生學(xué)號(hào)進(jìn)行查詢\n2. 通過學(xué)生姓名進(jìn)行查詢\n3. 按其他鍵取消操作\n";int select;cin >> select;while (cin.fail()){// cin輸入異常處理cin.clear();cin.ignore();cout << "輸入錯(cuò)誤,請(qǐng)重新輸入:";cin >> select;}switch (select){case 1:{string number;cout << "請(qǐng)輸入待查找學(xué)生的學(xué)號(hào):" << endl;cin >> number;int index = SearchStudentListByNumber(stu_list, number); // 查詢FindStudentListByIndex(stu_list, index);break;}case 2:{string name;cout << "請(qǐng)輸入待查找學(xué)生的姓名:" << endl;cin >> name;int index = SearchStudentListByName(stu_list, name); // 查詢FindStudentListByIndex(stu_list, index);break;}default:{cout << "操作取消成功!" << endl;system("pause");system("cls");return;break;}} }/*** 2.6 刪除學(xué)生信息*/ // 根據(jù)查詢到的index位序,對(duì)學(xué)生信息進(jìn)行刪除 bool DeleteStudentListByIndex(StudentList &stu_list, int index) {if (index == -2){cout << "當(dāng)前學(xué)生列表為空!" << endl;system("pause");system("cls");return false;}else if (index == -1){cout << "查無此人!" << endl;system("pause");system("cls");return false;}else{for (int i = index; i < stu_list.stu_size; ++i)stu_list.stu_array[i] = stu_list.stu_array[i + 1];stu_list.stu_size--;cout << "刪除成功!" << endl;system("pause");system("cls");return true;} }// 刪除學(xué)生信息總函數(shù),設(shè)計(jì)刪除操作的總邏輯以及對(duì)內(nèi)部小函數(shù)進(jìn)行調(diào)用 bool DeleteStudentList(StudentList &stu_list) {// cout << "通過輸入 學(xué)生學(xué)號(hào) 刪除請(qǐng)按 1,通過輸入 學(xué)生姓名 刪除請(qǐng)按 2,按其他鍵取消操作:" << endl;cout << "請(qǐng)選擇操作選項(xiàng):\n1. 通過學(xué)生學(xué)號(hào)進(jìn)行查詢并刪除\n2. 通過學(xué)生姓名進(jìn)行查詢并刪除\n3. 按其他鍵取消操作\n";int select;cin >> select;while (cin.fail()){ // cin輸入異常處理cin.clear();cin.ignore();cout << "輸入錯(cuò)誤,請(qǐng)重新輸入:";cin >> select;}switch (select){case 1:{string number;cout << "請(qǐng)輸入待刪除學(xué)生的學(xué)號(hào):" << endl;cin >> number;int index = SearchStudentListByNumber(stu_list, number); // 查詢DeleteStudentListByIndex(stu_list, index);break;}case 2:{string name;cout << "請(qǐng)輸入待刪除學(xué)生的姓名:" << endl;cin >> name;int index = SearchStudentListByName(stu_list, name);DeleteStudentListByIndex(stu_list, index);break;}default:{cout << "操作取消成功!" << endl;system("pause");system("cls");return false;break;}} }/*** 2.7 修改學(xué)生信息*/ // 根據(jù)查詢到的index位序,對(duì)學(xué)生信息進(jìn)行修改 bool ModifyStudentListByIndex(StudentList &stu_list, int index) {if (index == -2){cout << "當(dāng)前學(xué)生列表為空!" << endl;system("pause");system("cls");return false;}else if (index == -1){ // ==可不能寫成=,那就會(huì)為 真 條件,必執(zhí)行此分支cout << "查無此人!" << endl;system("pause");system("cls");return false;}else{cout << "查找成功!" << endl;cout << "請(qǐng)輸入想要修改的信息項(xiàng):\n1. 學(xué)號(hào)\n2. 姓名\n3. 性別\n4. 年齡\n5. 成績(jī)\n"<< endl;int select2;cin >> select2;switch (select2){case 1:{string number;cout << "請(qǐng)輸入新學(xué)號(hào):" << endl;while (true){cin >> number;if (SearchStudentListByNumber(stu_list, number) == -1){ // 修改則該生必存在,前面的分支已經(jīng)確定。stu_list.stu_array[index].number = number;break;}elsecout << "學(xué)號(hào)重復(fù),請(qǐng)輸入新學(xué)號(hào):";}break;}case 2:{string name;cout << "請(qǐng)輸入新姓名:" << endl;cin >> name;stu_list.stu_array[index].name = name;break;}case 3:{cout << "請(qǐng)輸入新性別:" << endl;cout << "1 -- 男" << endl;cout << "2 -- 女" << endl;int sex = 0;while (true){ // 簡(jiǎn)單的輸入合法性判斷cin >> sex;if (sex == 1 || sex == 2){stu_list.stu_array[index].sex = sex;break;}cout << "輸入有誤,請(qǐng)重新輸入:" << endl;}break;}case 4:{cout << "請(qǐng)輸入新年齡:" << endl;int age = 0;while (true){ // 簡(jiǎn)單的輸入合法性判斷cin >> age;if (age > 0 && age < 150){stu_list.stu_array[index].age = age;break;}cout << "輸入有誤,請(qǐng)重新輸入:" << endl;}break;}case 5:{cout << "請(qǐng)輸入新成績(jī):" << endl;int score = 0;for (int i = 0; i < 3; ++i){while (true){ // 簡(jiǎn)單的輸入合法性判斷cin >> score;if (score >= 0 && score <= 100){stu_list.stu_array[index].score[i] = score;break;}cout << "輸入有誤,請(qǐng)重新輸入:" << endl;}}break;}default:break;}cout << "修改成功!" << endl;system("pause");system("cls");return true;} }// 修改學(xué)生信息總函數(shù),設(shè)計(jì)修改操作的總邏輯以及對(duì)內(nèi)部小函數(shù)進(jìn)行調(diào)用 bool ModifyStudentList(StudentList &stu_list) {// cout << "通過輸入 學(xué)生學(xué)號(hào) 修改請(qǐng)按 1,通過輸入 學(xué)生姓名 修改請(qǐng)按 2,按其他鍵取消操作:" << endl;cout << "請(qǐng)選擇操作選項(xiàng):\n1. 通過學(xué)生學(xué)號(hào)進(jìn)行查詢并修改\n2. 通過學(xué)生姓名進(jìn)行查詢并修改\n3. 按其他鍵取消操作\n";int select;cin >> select;switch (select){case 1:{string number;cout << "請(qǐng)輸入待修改學(xué)生的學(xué)號(hào):" << endl;cin >> number;int index = SearchStudentListByNumber(stu_list, number); // 查詢ModifyStudentListByIndex(stu_list, index);break;}case 2:{string name;cout << "請(qǐng)輸入待修改學(xué)生的姓名:" << endl;cin >> name;int index = SearchStudentListByName(stu_list, name); // 查詢ModifyStudentListByIndex(stu_list, index);break;}default:{cout << "操作取消成功!" << endl;system("pause");system("cls");return false;break;}}return true; }/*** 2.8 根據(jù)學(xué)習(xí)成績(jī)排序*/ bool SortStudentList(StudentList &stu_list) {if (stu_list.stu_size == 0){cout << "學(xué)生列表為空!" << endl;system("pause");system("cls");return false;}int n;cout << "請(qǐng)選擇數(shù)據(jù)項(xiàng)進(jìn)行排序:\n1. 成績(jī)1——C語言成績(jī)\n2. 成績(jī)2——數(shù)學(xué)成績(jī)\n3. 成績(jī)3——英語成績(jī)\n";cin >> n; // 排序依據(jù)項(xiàng),減1后映射到數(shù)組StudentInfo temp; // 中間變量for (int i = 0; i < stu_list.stu_size - 1; ++i){ // 冒泡排序bool flag = false;for (int j = 0; j < stu_list.stu_size - 1 - i; ++j)if (stu_list.stu_array[j].score[n - 1] > stu_list.stu_array[j + 1].score[n - 1]){temp = stu_list.stu_array[j];stu_list.stu_array[j] = stu_list.stu_array[j + 1];stu_list.stu_array[j + 1] = temp;flag = true;}if (flag == false) // 本躺遍歷后沒有進(jìn)行交換,說明表已經(jīng)有序,直接退出break;}cout << "排序后的學(xué)生信息:" << endl;ShowStudentList(stu_list);// system("pause"); // ShowStudentList()有系統(tǒng)暫停了// system("cls");return true; }/*** 2.9 清空學(xué)生信息*/ bool ClearStudentList(StudentList &stu_list) {if (stu_list.stu_size == 0){cout << "學(xué)生列表已為空!" << endl;system("pause");system("cls");return false;}cout << "請(qǐng)?jiān)俅未_認(rèn)是否清空所有學(xué)生信息?(y/n)" << endl;char input;while (true){cin >> input;switch (tolower(input)){case 'y':{cout << "請(qǐng)輸入管理員密碼:";string code;while (true){cin >> code;if (code == CODE){stu_list.stu_size = 0; // 核心語句cout << "成功清空所有學(xué)生信息!" << endl;system("pause");system("cls");return true;}else if (code == "Q"){cout << "取消操作成功!" << endl;system("pause");system("cls");return true;}else{cout << "密碼輸入錯(cuò)誤!請(qǐng)重新輸入(輸入 Q 取消本次操作。):";}}break;}case 'n':{cout << "取消清空操作成功!" << endl;system("pause");system("cls");return false;}default:{cout << "請(qǐng)輸入字母 y 或者 n:";break;}}}/*if (input == "yes" || input == "YES") {cout << "請(qǐng)輸入管理員密碼:";string code;while (true) {cin >> code;if (code == CODE) {stu_list.stu_size == 0;cout << "成功清空所有學(xué)生信息!" << endl;system("pause");system("cls");return true;} else {cout << "密碼輸入錯(cuò)誤!請(qǐng)重新輸入:" << endl;}}} else {cout << "取消清空操作成功!" << endl;system("pause");system("cls");return false;}*/ }/*** 2.10 文件讀寫*/// 從文件讀取學(xué)生信息 bool ReadStudentInfoFromTxt(StudentList &stu_list) {char txt_path[50];cout << "請(qǐng)輸入文件路徑:";cin >> txt_path; // 輸入文件地址FILE *fp;// StudentInfo *p = (StudentInfo *)malloc(sizeof(StudentInfo) * TEMPSIZE); // c方式,為指針分配空間// StudentList stu2;// StudentInfo *p = stu2.stu_array;StudentInfo *p = new StudentInfo[TEMPSIZE]; // c++方式動(dòng)態(tài)分配內(nèi)存if ((fp = fopen(txt_path, "rt")) == NULL){printf("Error on open \"%s\" file!\n", txt_path);system("pause");system("cls");return false;}while (true){// 判滿if (stu_list.stu_size >= MAX){cout << "學(xué)生列表已滿,無法繼續(xù)添加!" << endl;system("pause");system("cls");return false;}// 讀出fread(p, sizeof(StudentInfo), 1, fp);if (!feof(fp)){// 打印cout << "學(xué)號(hào)\t\t"<< "姓名\t\t"<< "性別\t\t"<< "年齡\t\t"<< "成績(jī)1\t成績(jī)2\t成績(jī)3\n";cout << p->number << "\t\t";cout << p->name << "\t\t";cout << (p->sex == 1 ? "男" : "女") << "\t\t";cout << p->age << "\t\t";for (int j = 0; j < 3; ++j)cout << p->score[j] << "\t";cout << endl;// 保存stu_list.stu_array[stu_list.stu_size].number = p->number;stu_list.stu_array[stu_list.stu_size].name = p->name;stu_list.stu_array[stu_list.stu_size].sex = p->sex;stu_list.stu_array[stu_list.stu_size].age = p->age;for (int j = 0; j < 3; ++j)stu_list.stu_array[stu_list.stu_size].score[j] = p->score[j];stu_list.stu_size++; // 學(xué)生表長(zhǎng)+1p++; // 中間變量指針后移}else{fclose(fp);cout << "讀取完畢!" << endl;system("pause");system("cls");return true;}} }// 保存學(xué)生信息到文件 bool WriteStudentListToTxt(StudentList stu_list) {if (IsEmpty(stu_list)){cout << "學(xué)生列表目前為空!無需保存。" << endl;system("pause");system("cls");return false;}else{char txt_path[50];cout << "請(qǐng)輸入文件路徑:";cin >> txt_path; // 輸入文件地址FILE *fp;StudentInfo *p;p = stu_list.stu_array; // 令指針指向?qū)W生表if ((fp = fopen(txt_path, "wt")) == NULL){ // 以 寫模式、二進(jìn)制類型 打開文件printf("Error on open \"%s\" file!", txt_path);system("pause");system("cls");return false;}// for (int i = 0; i < stu_list.stu_size; ++i)// fwrite(p, sizeof(StudentInfo), 1, fp);fwrite(p, sizeof(StudentInfo), stu_list.stu_size, fp); // 寫入學(xué)生信息fclose(fp); // 關(guān)閉文件cout << "保存成功!" << endl;system("pause");system("cls");return true;} }// 清空文件所有學(xué)生信息 bool ClearStudentInfoInTxt() {char txt_path[50];cout << "請(qǐng)確認(rèn)是否繼續(xù)清空文件中所有學(xué)生信息?(y/n)" << endl;char input;while (true){cin >> input;switch (tolower(input)){case 'y':{cout << "請(qǐng)輸入管理員密碼:";string code;while (true){cin >> code;if (code == CODE){cout << "請(qǐng)輸入文件路徑:";cin >> txt_path; // 輸入文件地址FILE *fp;if ((fp = fopen(txt_path, "wb")) == NULL){ // 以 wb模式 打開文件,已存在則刪除新建,不存在則建立。printf("Error on open \"%s\" file!", txt_path);system("pause");system("cls");return false;}fclose(fp);cout << "成功清空文件所有學(xué)生信息!" << endl;system("pause");system("cls");return true;}else if (code == "Q"){cout << "取消操作成功!" << endl;system("pause");system("cls");return true;}else{cout << "密碼輸入錯(cuò)誤!請(qǐng)重新輸入(輸入 Q 取消本次操作。):";}}break;}case 'n':{cout << "取消清空操作成功!" << endl;system("pause");system("cls");return false;}default:{cout << "請(qǐng)輸入字母 y 或者 n:";break;}}} }/*** 2.11 學(xué)生成績(jī)統(tǒng)計(jì)*/ // 求第 i 門成績(jī)最高分 float FindHighestScore(StudentList stu_list, int i) {float max = stu_list.stu_array[0].score[i - 1];for (int j = 1; j < stu_list.stu_size; ++j)if (stu_list.stu_array[j].score[i - 1] > max)max = stu_list.stu_array[j].score[i - 1];return max; }// 求第 i 門成績(jī)最低分 float FindLowestScore(StudentList stu_list, int i) {float min = stu_list.stu_array[0].score[i - 1];for (int j = 1; j < stu_list.stu_size; ++j)if (stu_list.stu_array[j].score[i - 1] < min)min = stu_list.stu_array[j].score[i - 1];return min; }// 求第 i 門成績(jī)平均分 float FindAverageScore(StudentList stu_list, int i) {float avg = 0.0;for (int j = 0; j < stu_list.stu_size; ++j)avg += stu_list.stu_array[j].score[i - 1];return avg / stu_list.stu_size; }// 求不及格人數(shù) int CountFlunks(StudentList stu_list, int i) {int count = 0;for (int j = 0; j < stu_list.stu_size; ++j)if (stu_list.stu_array[j].score[i - 1] < 60)count++;return count; }// 求優(yōu)秀人數(shù) int CountExcellentStudents(StudentList stu_list, int i) {int count = 0;for (int j = 0; j < stu_list.stu_size; ++j)if (stu_list.stu_array[j].score[i - 1] > 80)count++;return count; }// 成績(jī)統(tǒng)計(jì) void StudentScoreStatistics(StudentList stu_list) {int select = 0, index = 0;cout << "成績(jī)統(tǒng)計(jì)開始……\n請(qǐng)選擇統(tǒng)計(jì)依據(jù)項(xiàng):\n1. C語言成績(jī)\n2. 數(shù)學(xué)成績(jī)\n3. 英語成績(jī)\n";cin >> index;while (1){cout << "請(qǐng)選擇統(tǒng)計(jì)內(nèi)容:\n1. 最高分\n2. 最低分\n3. 平均分\n4. 不及格人數(shù)\n5. 優(yōu)秀人數(shù)\n0. 取消操作返回上級(jí)菜單\n";cin >> select;switch (select){case 1:cout << "該科目成績(jī)的最高分: " << FindHighestScore(stu_list, index) << endl;system("pause");system("cls");break;case 2:cout << "該科目成績(jī)的最低分: " << FindLowestScore(stu_list, index) << endl;system("pause");system("cls");break;case 3:cout << "該科目成績(jī)的平均分: " << FindAverageScore(stu_list, index) << endl;system("pause");system("cls");break;case 4:cout << "該科目成績(jī)不合格人數(shù): " << CountFlunks(stu_list, index) << endl;system("pause");system("cls");break;case 5:cout << "該科目成績(jī)優(yōu)秀人數(shù): " << CountExcellentStudents(stu_list, index) << endl;system("pause");system("cls");CountExcellentStudents(stu_list, index);break;case 0:cout << "取消成功!!!" << endl;system("pause");system("cls");return;default:{cout << "輸入錯(cuò)誤!請(qǐng)重新輸入!\n";break;}}} }// 學(xué)生信息統(tǒng)計(jì)總函數(shù) bool StudentInfoStatistics(StudentList stu_list) {int select = 0;// cout << "學(xué)生信息統(tǒng)計(jì)開始……\n請(qǐng)選擇統(tǒng)計(jì)選項(xiàng):\n1. 成績(jī)統(tǒng)計(jì)\n2. 成績(jī)排名\n";while (1){cout << "學(xué)生信息統(tǒng)計(jì)開始……\n請(qǐng)選擇統(tǒng)計(jì)選項(xiàng):\n1. 成績(jī)統(tǒng)計(jì)\n2. 成績(jī)排名\n0. 取消操作返回主菜單\n";cin >> select;switch (select){case 1:StudentScoreStatistics(stu_list);break;case 2:SortStudentList(stu_list);break;case 0:cout << "取消成功!!!" << endl;system("pause");system("cls");return false;default:cout << "輸入錯(cuò)誤!請(qǐng)重新輸入:";break;}}return true; }/*** 3. 主函數(shù)*/ int main() {StudentList stus_list; // 定義全局結(jié)構(gòu)體變量InitStudentList(stus_list); // 初始化int select = 0;while (true){ // 死循環(huán),只要里面設(shè)置return就行。ShowMenu();cout << "請(qǐng)輸入操作選項(xiàng):";cin >> select;while (cin.fail()){ // cin輸入異常處理cin.clear();cin.ignore();cout << "輸入錯(cuò)誤,請(qǐng)重新輸入:";cin >> select;}switch (select){case 1: // 1. 添加學(xué)生信息AddStudentList(stus_list);break;case 2: // 2. 顯示學(xué)生信息ShowStudentList(stus_list);break;case 3: // 3. 刪除學(xué)生信息DeleteStudentList(stus_list);break;case 4: // 4. 查詢學(xué)生信息FindStudentList(stus_list);break;case 5: // 5. 修改學(xué)生信息ModifyStudentList(stus_list);break;case 6: // 6. 統(tǒng)計(jì)學(xué)生信息StudentInfoStatistics(stus_list);break;case 7: // 7. 清空學(xué)生信息ClearStudentList(stus_list);ClearStudentInfoInTxt();break;case 8: // 8. 保存學(xué)生信息到文件WriteStudentListToTxt(stus_list);break;case 9: // 9. 從文件讀取學(xué)生信息ReadStudentInfoFromTxt(stus_list);break;case 0:{// 0. 退出管理系統(tǒng)cout << "歡迎下次使用!" << endl;exit(0);// return 0;}default:cout << "輸入錯(cuò)誤,請(qǐng)重新輸入!" << endl;break;}}return 0; }/** 文件名后綴為 .cpp* 用 VSCode 編輯代碼的話,需要把文件改為以 GBK 模式保存打開,(下載個(gè) Code Runner 插件會(huì)很舒服)*/四、總結(jié)
1. BUGS & QUESTIONS & ANSWERS
- if (SearchStudentListByNumber(stu_list, number) == -1) {...}
- try catch
- if(cin.fail())
- 把冒泡排序、快速排序等排序算法的ElemType換一下就行。
- 用 printf 進(jìn)行格式化輸出。
- stu_list.stu_array[stu_list.stu_size].name = name; 改為 stu_list.stu_array[index]...
- ???
- 中間變量初始化 score 的時(shí)候類型定義錯(cuò)了。定義為 int 了。
- 用fwrite、fread+feof
- 用 指針變量 存儲(chǔ)信息,需要提前分配好空間!!!
struct StudentInfo *p = (struct StudentInfo *)malloc(sizeof(struct StudentInfo) * TEMPSIZE); - 明明正常運(yùn)行,學(xué)生表卻沒有改變! ==> 函數(shù)參數(shù)要加引用!!!
- 總是多讀取一行?解決 feof() 判斷文件末尾多讀一次的方法
- 先 if(!feof(fp)) 再 fread() 改為 先fread()再if
- 從文件讀取學(xué)生信息可能與新輸入過的信息學(xué)號(hào)沖突
因?yàn)橹挥型ㄟ^了 添加學(xué)生 函數(shù)的限制條件,才能保存,所以文件內(nèi)的數(shù)據(jù)都是正常合法的,只有 學(xué)號(hào)信息的唯一性 無法保證。
- 法1:進(jìn)入系統(tǒng)強(qiáng)制從文件讀取信息刷新學(xué)生表,然后再利用添加學(xué)生信息函數(shù)的判重去限制 ?
- 法2:從文件讀取增加學(xué)號(hào)重復(fù)判斷。
- 讀取的數(shù)據(jù),其他信息都正常,學(xué)號(hào)、姓名是空的?而且同一次程序中讀取學(xué)生數(shù)據(jù)就沒問題,保存后退出程序,下次運(yùn)行就讀不到 學(xué)號(hào)和名字。
- (是string的問題,還是編碼問題?)???
- 但是,cin/cout 是真的好用!!不需要自己填寫類型。
- string也是,比字符數(shù)組好用多了。
- 函數(shù)傳引用,這樣修改形參實(shí)現(xiàn)對(duì)實(shí)參變量的修改,不用傳引用的話,只能用 指針。
- 不能!!!最好是用 tolower() 轉(zhuǎn)變?yōu)樾?#xff0c;再進(jìn)行 case。
2. SUMMARY
該系統(tǒng)中我用了多種結(jié)構(gòu)進(jìn)行嘗試。不僅是 語法關(guān)鍵字選擇,還有輸入語句 cin 位置的區(qū)別(循環(huán)內(nèi)/循環(huán)外)
- (1) 指針
AddStudentList (StudentList* stu_list)+傳地址& - (2) 傳引用
AddStudentList (StudentList &stu_list)
- (1) char數(shù)組 + strcmp等字符串函數(shù) + %s (char類型數(shù)據(jù)只能直接輸入/用字符串函數(shù),不能直接賦值)
- (2) string + 可直接用字符串賦值 + cin直接輸入 等便捷操作
- break只能中斷switch/循環(huán),return能中斷一個(gè)函數(shù),exit中斷一個(gè)程序。
-
(1) 添加學(xué)生信息
- 判滿
- 在表尾插入新元素
- 當(dāng)前表大小+1
- while(true)+if,break+SearchStudentListByNumber 實(shí)現(xiàn)學(xué)號(hào)查重,輸入合法性判斷等
- 輸出注意:cout << (stu_list.stu_array[i].sex == 1 ? "男" : "女");
-
(2) 顯示學(xué)生信息
- 判空
- 顯示學(xué)生性別信息需要用三目運(yùn)算符進(jìn)行簡(jiǎn)單轉(zhuǎn)換顯示
-
(3) 刪除學(xué)生信息
- 查詢到學(xué)生信息 SearchStudentListByNumber/SearchStudentListByName
- 判空
- 將 待刪學(xué)生信息 后的信息往前移一位,覆蓋 待刪學(xué)生信息
- 表長(zhǎng)度-1
-
(4) 查詢學(xué)生信息
- 順序查找到學(xué)生位序 SearchStudentListByNumber/SearchStudentListByName
- 根據(jù)返回位序信息進(jìn)行相關(guān)信息顯示
-
(5) 修改學(xué)生信息
- 查詢到學(xué)生信息,返回 index
- 對(duì) stu_array[index] 進(jìn)行修改。直接賦值新值即可。
-
(6) 清空學(xué)生信息
- 直接令 stu_size = 0 即可
-
(7) 排序?qū)W生信息
- 用 冒泡排序/快速排序等排序算法 的邏輯,對(duì)學(xué)生表進(jìn)行排序。
以 學(xué)生表元素的成績(jī)?cè)?為大小判斷依據(jù),以 學(xué)生表元素 為中間變量進(jìn)行位置交換。
- 用 冒泡排序/快速排序等排序算法 的邏輯,對(duì)學(xué)生表進(jìn)行排序。
-
(0) 退出管理系統(tǒng)
- exit(0)
該系統(tǒng)也沒用到什么復(fù)雜的數(shù)據(jù)結(jié)構(gòu),就是最簡(jiǎn)單的順序表。
希望對(duì)大家有所幫助和啟發(fā)~
一鍵三連!!!😎😎😎
總結(jié)
以上是生活随笔為你收集整理的班级学生成绩管理系统——C/C++实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 液位传感器与压力传感器的联系与区别
- 下一篇: https://zhuanlan.zhi