【C++】學生管理系統
一道非常經典的C語言題目,用C++實現
題目如下:
- 輸入功能:由鍵盤輸入10個學生的學號、姓名、三科成績,並計算出平均成績和總成績,然後將它存入檔案stud.dat。
- 插入功能:按學號增加一個學生資訊,並將其插入到stud.dat中。
- 排序功能,按要求對學生資訊進行排序,分為按學號和按總成績進行排序兩種情形,並輸出結果。
- 查詢功能:按要求查詢學生資訊,分為按學號和姓名進行查詢兩種情形,並輸出結果。
- 刪除功能:按要求將學生資訊刪除,分為按學號和姓名進行刪除兩種情形。
- 輸出功能:按學號輸出學生資訊。
整體思路:
- 程式啟動的時候判斷檔案(stu.dat)是否存在,如果檔案不存在,則正常執行,如果檔案存在,先獲取檔案中學生的個數,根據學生的個數建立物件陣列,將內容建立成學生物件,儲存在物件陣列1裡,再向下執行。
- 用Switch語句來判斷不同的輸入。
- 新增學生,根據 原來物件陣列1儲存的人數+新增的人數 來確定新的動態陣列2的大小,將原本物件陣列1內的內容儲存在新的物件陣列2裡,再將新增的內容儲存在後面,每次新增完,直接儲存到檔案。
- 排序學生,根據學號或者姓名,寫一個陣列的氣泡排序即可
- 查詢學生,寫一個函式,判斷學生是否存在,如果存在返回學生所在陣列的下標,根據下標輸出內容
- 刪除學生,用查詢學生寫的函式,根據下標刪除學生
- cout物件陣列裡的內容就完事
實現程式碼
#include <iostream> #include<fstream> #include<string> #define line for (int n = 0; n <= 100; n++) cout << "-" #define FILENAME "stdu.dat" using namespace std; class student { //學生類 public: int Is_Exist(string stuId, int a); int get_student_number(); //獲取檔案中學生人數 bool File_Is_Empty; //檔案是否為空的標識 student *studentArray; //將檔案中的內容,以student物件方式儲存在studentArray[]陣列中 int student_number; //學生人數 string studentId; //學號 string name; //姓名 float score[3];//成績*3 float Total; // 總分 int Average;//平均分 void sort(int n=1); //排序函式 void delete_stu(); //刪除學生 void init(); //初始化內容,將檔案中的內容讀到studentArray中 void save(); //儲存檔案 void show();//展示介面 void add_stu(int number = 1); //新增學生 void showInfo(); //展示學生資訊 void search();//搜尋學生 student() //預設建構函式,判斷檔案是否為空,設定File_Is_Empty值 { ifstream ifs; ifs.open(FILENAME, ios::in); if (!ifs.is_open()) { this->student_number = 0; this->studentArray = NULL; this->studentId = "0"; this->name = "0"; this->score[0] = 0; this->Average = 0; this->Total = 0; this->File_Is_Empty = true; ifs.close(); return; } char c; ifs >> c; if (ifs.eof()) { //檔案空 this->student_number = 0; this->studentArray = NULL; this->studentId = "0"; this->name = "0"; this->score[0] = 0; this->Average = 0; this->Total = 0; this->File_Is_Empty = true; ifs.close(); return; } int num = this->get_student_number(); //獲取檔案中學生數量 this->student_number = num; //cout << "現在學生人數為:" << num << endl;; //system("pause"); }; ~student() //解構函式 { delete[]this->studentArray; this->studentArray = NULL; //防止指標變為野指標 } student(string stuId,string stuName, float stuScore[3]) //帶引數的建構函式 { this->studentId = stuId; this->name = stuName; for (int i = 0; i < 3; i++) this->score[i] = stuScore[i]; this->Average = (stuScore[0] + stuScore[1] + stuScore[2]) / 3; this->Total = stuScore[0] + stuScore[1] + stuScore[2]; }; }; void student::sort(int n) //排序,當n=1的時候為按學號排序,n=2為按總成績排序 { int num1; //學號在設計的時候是string型別,用int型別排序需要atoi,用num接收轉換過的值 int num2; // student a; //用於交換物件陣列的中間變數 if (this->File_Is_Empty) //判斷檔案是否為空 { cout << "資料檔案不存在或者為空\n"; system("pause"); } else { cout << "3.學生資訊排序\n"; if (n == 1) { cout << "將學生資訊按學號順序排序\n"; for (int i = 0; i < this->student_number - 1; i++)//氣泡排序 { for (int t = 0; t < this->student_number - 1 - i; t++) { num1 = atoi(this->studentArray[t].studentId.c_str()); //將string型別變數變為int型別 num2 = atoi(this->studentArray[t + 1].studentId.c_str()); if (num1 > num2) a = this->studentArray[t + 1], this->studentArray[t + 1] = this->studentArray[t], this->studentArray[t] = a; } } } if (n == 2) { cout << "將學生資訊按總成績順序排序\n"; for (int i = 0; i < this->student_number - 1; i++)//氣泡排序 { for (int t = 0; t < this->student_number - 1 - i; t++) { if (this->studentArray[t].Total > this->studentArray[t + 1].Total) a = this->studentArray[t + 1], this->studentArray[t + 1] = this->studentArray[t], this->studentArray[t] = a; } } } } } void student::search() //查詢學生成績 { string id; int ret; //studentArray[]的下標,在Is_Exist()中 int a = 1; //判斷根據學號查詢還是姓名查詢 cout << "4.查詢學生成績\n" << "1.按照學號查詢\t2.根據姓名查詢\n輸入你的選項>"; cin >> a; if (a == 1) { cout << "請輸入學號:", cin >> id; ret = this->Is_Exist(id, 1); } else if (a == 2) { cout << "請輸入姓名:", cin >> id; ret = this->Is_Exist(id, 2); } else { ret = this->Is_Exist(id, 1); } if (ret == -1) { system("cls"); cout << "學生不存在" << endl; } else { cout << "查詢成功,下面為該學生資訊\n" << endl; cout << "學號:" << this->studentArray[ret].studentId << " 姓名:" << this->studentArray[ret].name << endl << "各門成績:語文:" << this->studentArray[ret].score[0] << " 數學:" << this->studentArray[ret].score[0] << " 英語:" << this->studentArray[ret].score[2] << " 平均成績:" << this->studentArray[ret].Average << " 總成績:" << this->studentArray[ret].Total << endl; } system("pause"); } int student::Is_Exist(string stuId,int a) { //a=1 則使用學生學號查詢 //a=2 則使用學生姓名查詢 if (File_Is_Empty) //判斷檔案是否不存在或者為空,如果為空則返回-2 { cout << "資料檔案不存在或者為空\n"; system("pause"); return -2; } for (int i = 0; i < this->student_number; i++) { if ((a==1)&&(this->studentArray[i].studentId == stuId)) //根據學號查詢 { return i; } if ((a == 2) && (this->studentArray[i].name == stuId)) //根據姓名查詢 { return i; } } return -1; //如果沒找到返回-1 } void student::delete_stu() //刪除學生 { int ret; //接收 Is_Exist的返回值,返回值是此學生在studentArray[]裡的下標 string id; //可以用來接收學號或者姓名 int a = 1; //判斷是按照學生學號尋找還是根據學生姓名尋找 cout << "5.刪除學生成績\n" << "1.按照學號刪除\t2.根據姓名刪除\n輸入你的選項>"; cin >> a; if (a == 1) //按照學生學號查詢 { cout << "請輸入學號:", cin >> id; ret = this->Is_Exist(id, 1); } else if(a==2)//按照學生姓名 { cout << "請輸入姓名:", cin >> id; ret = this->Is_Exist(id, 2); } else //預設按照學生學號進行查詢 { cout << "請輸入學號:", cin >> id; ret = this->Is_Exist(id, 1); } if (ret == -1) //返回值為-1則學生不存在 { system("cls"); cout << "學生不存在"<<endl; } else if(ret == -2) //返回值為-2檔案不存在或為空,直接退出函式 { return; } else //如果學生資訊存在,並且ret是studentArray[]中的下標 {//輸出要刪除的學生資訊 cout << "該學生的資訊將被刪除"<<endl; cout << "學號:" << this->studentArray[ret].studentId << " 姓名:" << this->studentArray[ret].name << endl << "各門成績:語文:" << this->studentArray[ret].score[0] << " 數學:" << this->studentArray[ret].score[0] << " 英語:" << this->studentArray[ret].score[2] << " 平均成績:" << this->studentArray[ret].Average << " 總成績:" << this->studentArray[ret].Total << endl; for (int i = ret; i < this->student_number - 1; i++) { this->studentArray[i] = this->studentArray[i + 1]; } this->student_number--; this->save(); } system("pause"); } void student::init() { string name; //用來儲存讀取到的姓名 string student_id;//用來儲存讀取到的學號 int i = 0; //識別符號,用來把例項化的類儲存到對應的物件陣列 float score[3]; //用來儲存讀取到的成績 float total; //用來儲存讀取到的成總分 int average; //用來儲存讀取到的平均分 ifstream inf; //例項化一個檔案物件 this->studentArray = new student[this->student_number]; //根據讀取到的學生數量開闢空間,學生數量 inf.open(FILENAME, ios::in); while (inf >> student_id && inf >> name && inf >> score[0]&& inf >> score[1] && inf >> score[2] && inf >> average && inf >> total) { //格式化讀取檔案,從檔案讀到變數 student stu(student_id, name, score); //使用讀到的值例項化student物件 this->studentArray[i] = stu; //把例項化的物件放到stu1物件的studentArray中 i++; } } int student::get_student_number() //獲取檔案中學生的數量,在add_stu()函式中加上需要增加的學生數量,為最新需要開闢的空間的大小 { string name; string student_id; int num=0; //每格式化讀取一塊資料,則加1人數 float score[3]; float total; int average; ifstream inf; inf.open(FILENAME, ios::in); while (inf >> student_id && inf >> name && inf >> score[0] && inf >> score[1] && inf >> score[2] && inf >> average && inf >> total) { num++; } inf.close(); return num; //返回學生數量 } void student::save() //將stu1中studentArray中的每個student物件儲存到檔案中 { ofstream ofs; ofs.open(FILENAME,ios::out); for (int i = 0; i < this->student_number; i++) { ofs << this->studentArray[i].studentId << " " << this->studentArray[i].name << " " << this->studentArray[i].score[0] << " " << this->studentArray[i].score[1] << " " << this->studentArray[i].score[2]<< " " <<this->studentArray[i].Average<<" "<< this->studentArray->Total<<" "; } } void student::showInfo() //顯示學生資訊 { if (this->File_Is_Empty) //建構函式裡的檔案識別符號,判斷檔案是否存在或者為空,每例項化一個物件都檢查一遍 { system("cls"); cout << "檔案不存在或內容為空,請先輸入資料\n"; } else { //檔案不為空則輸出stu1中studentArray中儲存的內容 for (int i=0;i<this->student_number;i++) { cout << "學號:" << this->studentArray[i].studentId << " 姓名:" << this->studentArray[i].name << endl << "各門成績:語文:" << this->studentArray[i].score[0] << " 數學:" << this->studentArray[i].score[1] << " 英語:" << this->studentArray[i].score[2] << " 平均成績:" << this->studentArray[i].Average << " 總成績:" << this->studentArray[i].Total << endl; line; cout << endl; } } system("pause"); } void student::add_stu(int add_number) //新增學生 { //計算需要的新的空間大小 int newsize = this->student_number + add_number; //需要開闢的空間 = 檔案中學生的人數+需要新增的數量 //cout << "newxize=" << newsize; student *newspace = new student[newsize]; //開闢記憶體空間 student *stu3; string name; string studentId; float score[3]; if (this->studentArray!= NULL) //如果studentArray不為空就先將studentArray中的內容先複製到newspace陣列中,再在newspace中增加學生資訊, //最後再將newspace的內容複製到studentArray中,實現動態陣列 { for (int i = 0; i < this->student_number; i++) { newspace[i] = this->studentArray[i]; } } for (int i = 0; i < add_number; i++) //輸入學生資訊 { cout << "請輸入學生姓名:", cin >> name, cout << endl; cout << "請輸入學生學號:", cin >> studentId, cout << endl; cout << "請輸入學生語文成績:", cin >> score[0], cout << endl; cout << "請輸入學生數學成績:", cin >> score[1], cout << endl; cout << "請輸入學生英語成績:", cin >> score[2], cout << endl; line; cout << endl; student stu3(studentId, name, score); //將輸入的內容例項化成物件 newspace[this->student_number + i] = stu3; //將物件依次儲存到newspace中 } delete[] this->studentArray; this->studentArray = newspace; //將newspace賦給studentArray,用來在別的成員函式中訪問 this->student_number = newsize; //更新學生人數大小 this->File_Is_Empty = false; // 輸入了內容以後,檔案不為空 this->save(); //儲存到檔案中 cout << "新增成功"<<endl; system("pause"); } void student::show() { cout << "1.輸入學生成績" << endl << "2.增加學生成績" << endl << "3.學生資訊排序" << endl << "4.查詢學生成績" << endl << "5.刪除學生成績" << endl << "6.顯示學生成績" << endl << "7.安全退出系統" << endl; line; cout << endl; cout<< "輸入你的選擇>:"; } student stu1; //例項化物件,此時已經得到檔案中的學生數量 int main() { int choice=7; stu1.init(); // 將檔案裡的內容按照格式讀入記憶體,儲存到 // cout << "stu1裡的人數" << stu1.student_number; // system("pause"); while (true) { system("cls"); stu1.show(); cin >> choice; line; cout << endl; if (cin.good() && choice <= 7 && choice >= 1) //判斷使用者輸入是否合法 { switch (choice) { case 1: //新增學生功能,預設引數為1,用來增加學生時直接呼叫,初始化新增十個學生時傳遞引數10 stu1.add_stu(10); break; case 2: //增加學生,要求按照學號順序插入,則在增加學生後呼叫排序函式,再進行儲存 { stu1.add_stu(); stu1.sort(); stu1.save(); } break; case 3: //排序功能 { int n = 1; cout << "1.按照學號排序\t2.按照總成績排序\n"; cin >> n; stu1.sort(n); stu1.showInfo(); } break; case 4: //搜尋功能 stu1.search(); break; case 5: //刪除功能 stu1.delete_stu(); break; case 6: //顯示學生資訊 stu1.showInfo(); break; case 7: //退出程式 return 0; break; default: system("cls"); break; } } else { //歸位cin識別符號,不至於死迴圈 cin.clear(); cin.ignore(); cout << "非法資料"<<endl; system("pause"); } } }
介面簡陋,加點“ - ”,加點“ * ”,可能會好點,或者乾脆用qt寫個介面也可以