C++實現控制檯學生學籍管理系統

Thrush發表於2021-04-17

操作流程

建立檔案

建立管理類

​ 管理類負責的內容如下:

  • 提供與使用者的溝通選單介面

  • 實現對職工增刪改查的操作

  • 陣列資料與檔案的讀寫互動

選單功能實現

在StudentManager.h中定義ShowMenu()函式在StudentManager.cpp中實現顯示選單功能,便於與使用者互動,利用序號將所有功能顯示出來,便於使用者選擇以及,進行後期的使用。

程式碼如下

void StudentManager::Show_Menu()
{
	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
	cout << "~~~~~~~~~~~~~~~~學生學籍管理系統~~~~~~~~~~~~~~~~" << endl;
	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
	cout << "******************(0)退出系統*****************" << 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 << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
	cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}

退出功能

為各種功能提供介面

在main函式中為管理操作的函式提供介面,建立例項物件,呼叫物件內成員函式

實現程式碼

int main()
{

	StudentManager stu;
	int chioce;
	while (true)
	{
        system("color B1");//美化控制檯
		//顯示選單
		stu.Show_Menu();
		cout << "請輸入您的選擇:";
		cin >> chioce;
		switch (chioce)
		{
		case 0:stu.Exit_System();//退出系統
			break;
		case 1:stu.Add_Student();//錄入學生
			break;
		case 2:stu.ShowStudent();//顯示學籍
			break;
		case 3:stu.DeleteStudent();//刪除學生
			break;
		case 4:stu.ModStudent();//修改學生
			break;
		case 5:stu.FindStudent();//查詢學生
			break;
		case 6:stu.SortStudent();//學生排序
			break;
		case 7:stu.ClassifyStudent();//分類顯示
			break;
		case 8:stu.CleanStudent();//清空系統
			break;
		default://
			system("cls");
			break;
		}
		system("pause");
		
	}
	
	return 0;
}

退出功能實現

在StudentManager.h中定義Exit_System();函式

在StudentManager.cpp中實現函式功能,利用exit(0);實現程式的退出操作

程式碼實現如下:

void StudentManager::Exit_System()
{
	cout << "歡迎下次使用" << endl;
	system("pause");
	exit(0);
}

建立學生類

建立大一類

先建立學生類作為父類,然後定義各種成員屬性

大一類繼承學生抽象類,並重寫父類中的重虛擬函式

建立標頭檔案Grade01.h和原始檔Grade.cpp

程式碼實現如下

Grade01.h

#pragma once
#include"Student.h"

class Grade01:public Student
{
public:
	
	Grade01(int id, string name, int grade);
	void Show_Info();//顯示個人資訊
	string Get_Grade();//獲取年級名稱
};

Grade01.cpp

#include"Grade01.h"

Grade01::Grade01(int id,string name,int grade)
{
	this->m_id = id;
	this->m_name = name;
	this->m_grade = grade;
}
void Grade01::Show_Info()//顯示個人資訊
{
	cout << "學號:" << this->m_id << " "
		<< "姓名:" << this->m_name << " "
		<< "年級:" << this->Get_Grade() << endl;
}
string  Grade01::Get_Grade()//獲取年級名稱
{
	return (string)"大一";
}



建立大二類

與大一類上述程式碼相同不再贅述

建立大三類

與大一類上述程式碼相同不再贅述

建立大四類

與大一類上述程式碼相同不再贅述

新增學生

在StudentManager.h中新增屬性以及成員函式

根據學生的人數加上新增後的人數,開闢一塊新的空間記錄資料

系統整體利用指標陣列實現資料的臨時儲存,最終與檔案的操作配合使用,使資料轉存到檔案中

	//記錄人數
	int Student_Num;
	//學生陣列的指標
	Student** Student_Array;//指標陣列用來存Student* 的陣列(Student*)* Student_Array;

在StudentManager.cpp中建構函式中初始化

	//初始化人數
	this->Student_Num = 0;
	//初始化陣列指標
	this->Student_Array = NULL;

在StudentManager.cpp中實現成員函式

void StudentManager::Add_Student()
{
	cout << "請輸入新增學生數量" << endl;
	int addnum;
	cin >> addnum;
	if (addnum > 0)
	{
		//計算新空間大小
		int newsize = this->Student_Num + addnum;
		//開闢空間
		Student** newspace = new Student * [newsize];
		//將源空間的內容存放到新空間下
		if (this->Student_Array != NULL)
		{
			for (int i = 0; i < this->Student_Num; i++)
			{
				newspace[i] = this->Student_Array[i];
			}
		}
		//輸入新資料
		for (int i = 0; i < addnum; i++)
		{
			int id;
			string name;
			int select;
			cout << "請輸入第" << i + 1 << "個學生學號" << endl;
			cin >> id;
			cout << "請輸入第" << i + 1 << "個學生姓名" << endl;
			cin >> name;
			cout << "請輸入第" << i + 1 << "個學生年級編號" << endl;
			cout << "1、大一" << endl;
			cout << "2、大二" << endl;
			cout << "3、大三" << endl;
			cout << "4、大四" << endl;
			cin >> select;
			Student* student = NULL;
			switch (select)
			{
			case 1://大一
				student = new Grade01(id, name, 1);
				break;
			case 2://大2
				student = new Grade02(id, name, 1);
				break;
			case 3://大3
				student = new Grade03(id, name, 1);
				break;
			case 4://大4
				student = new Grade04(id, name, 1);
				break;
			default:
				break;
			}

			newspace[this->Student_Num + i] = student;
		}
		//釋放原有空間
		delete[]this->Student_Array;
		//更新空間指向
		this->Student_Array = newspace;
		//更新學生個數
		this->Student_Num = newsize;
		//提示
		cout << "新增成功" << addnum << "個學生" << endl;
        
	}
	else {
		cout << "輸入有誤" << endl;
	}
	system("pause");
	system("cls");
}

儲存檔案

void StudentManager::Save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out);//以寫檔案的方式開啟檔案
	for (int i = 0; i < this->Student_Num; i++)
	{
		ofs << this->Student_Array[i]->m_id << " "
			<< this->Student_Array[i]->m_name << " "
			<< this->Student_Array[i]->m_grade << " " << endl;
	}
	ofs.close();
}

初始化學生

在初始化學生之前,要判斷學生檔案狀態,分為三種情況

1、第一次使用檔案未建立

2、檔案存在,但是為空檔案

3、檔案和資料正常存在

首先在StudentManager.h中新增標誌檔案是否為空的標誌

若為空檔案,或者檔案不存在,則該bool型別的值返回true

bool FileIsEmpty;

修改StudentManager.cpp中的建構函式程式碼

StudentManager::StudentManager()
{
	
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	//檔案不存在情況
	if (!ifs.is_open())
	{
		cout << "檔案不存在" << endl;
		this->Student_Num = 0;//初始化人數為零
		this->FileIsEmpty = true;//標誌檔案為空
		this->Student_Array = NULL;//初始化陣列為空
		ifs.close();//關閉檔案
		return;
	}
	//檔案存在,並且沒有記錄
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		cout << "檔案為空" << endl;
		this->Student_Num = 0;
		this->FileIsEmpty = true;
		this->Student_Array = NULL;
		ifs.close();
		return;
	}
	int num = this->get_StudentNum();
	cout << "職工個數為:" << num << endl;
	this->Student_Num = num;
	//根據職工數建立陣列
	this->Student_Array = new Student * [this->Student_Num];
	this->InitStudent();
}

如果檔案不存在,則初始化檔案

檔案在不存在,或者為空的情況下,判斷檔案是否為空的標誌都為真

成功新增學生資訊後更改檔案不為空

初始化檔案

初始化Student* 型別的指標陣列,將Student型別的地址存到*Student****中

在StudentManager.cpp中實現

void StudentManager::InitStudent()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	int id;
	string name;
	int Grade;
	int index=0;
	while (ifs >> id && ifs >> name && ifs >> Grade)
	{
		Student* student = NULL;//根據年級建立student*的物件
		if (id == 1)
		{
			student = new Grade01(id, name, Grade);
		}else if(id==2)
		{
			student = new Grade02(id, name, Grade);
		}
		else if (id == 3)
		{
			student = new Grade03(id, name, Grade);
		}
		else
		{
			student = new Grade04(id, name, Grade);
		}
		//存放在陣列中
		this->Student_Array[index] = student;
		index++;
		
	}
}

顯示學生

void StudentManager::ShowStudent()
{
	if (this->FileIsEmpty)
	{
		cout << "檔案為空或者不存在" << endl;
	}
	else
	{
		for (int i = 0; i < this->Student_Num; i++)
		{
			//利用多型呼叫介面
			this->Student_Array[i]->Show_Info();
		}
	}
	system("pause");
	system("cls");
}

刪除學生

刪除學生之前判斷其是否存在

如果為空或者不存在,返回-1,如果存在,返回其下標

在StudentManager.cpp中實現

根據成員屬性匹配的到陣列的下標,便於後續索引型別的操作進行

int StudentManager::IsExist(int id)
{
	int index = -1;
	for (int i = 0; i < this->Student_Num; i++)
	{
		if (this->Student_Array[i]->m_id == id)
		{
			index = i;
			break;
		}
	}
	return index;
}

刪除,實現按照學號刪除

void StudentManager::DeleteStudent()
{
	if (this->FileIsEmpty)
	{
		cout << "檔案不存在或者記錄為空" << endl;
	}
	else
	{
		cout << "請輸入要刪除的學生學號" << endl;
		int id = 0;
		cin >> id;
		int index = this->IsExist(id);
		if (index != -1)
		{
			for (int i = index; i < this->Student_Num - 1; i++)
			{
				this->Student_Array[i] = this->Student_Array[i + 1];
			}
			this->Student_Num--;
			this->Save();//刪除後同步資料到檔案
			cout << "刪除成功" << endl;
		}
		else
		{
			cout << "刪除失敗,未找到該職工" << endl;
		}
	}
	system("pause");
	system("cls");
}

查詢學生

按照學生編號,按照學生姓名

void StudentManager::FindStudent()
{
	if (this->FileIsEmpty)
	{
		cout << "檔案不存在或者記錄為空!" << endl;
	}
	else
	{
		cout << "請輸入查詢的方式:" << endl;
		cout << "1、按學號查詢" << endl;
		cout << "2、按姓名查詢" << endl;

		int select = 0;
		cin >> select;
		if (select == 1)//按照學號查詢
		{
			int id;
			cout << "請輸入查詢的學號" << endl;
			cin >> id;
			int ret = this->IsExist(id);
			if (ret != -1)
			{
				cout << "查詢成功,該學生資訊如下" << endl;
				this->Student_Array[ret]->Show_Info();
			}
			else
			{
				cout << "查詢失敗,查無此人" << endl;
			}
		}
		else if (select == 2)//按姓名查詢
		{
			string name;
			cout << "請輸入查詢的姓名" << endl;
			cin >> name;
			bool flag = false;//查詢到的標誌
			for (int i = 0; i < this->Student_Num; i++)
			{
				if (this->Student_Array[i]->m_name == name)
				{
					cout << "查詢成功,資訊如下" << endl;
					flag = true;
					this->Student_Array[i]->Show_Info();
				}
			}
			if (flag == false)
			{
				cout << "查詢失敗,查無此人!!" << endl;
			}
		}
		else
		{
			cout << "輸入選項有誤" << endl;
		}
	}
	system("pause");
	system("cls");
}

修改學生資訊

按照編號對職工資訊儲存修改

利用IsExist函式獲取學生陣列元素下標,然後對應進行修改,記錄儲存

void StudentManager::ModStudent()
{
	if (this->FileIsEmpty)
	{
		cout << "檔案不存在,或記錄為空" << endl;
	}
	else
	{
		cout << "請輸入要修改的學生學號" << endl;
		int id;
		cin >> id;
		int ret = this->IsExist(id);
		if (ret != -1)
		{
			delete this->Student_Array[ret];
			int newid = 0;
			string newname = "";
			int select = 0;
			cout << "查到" << id << "號學生,請輸入新學號" << endl;
			cin >> newid;
			cout << "請輸入新姓名" << endl;
			cin >> newname;
			cout << "請輸入年級" << endl;
			cout << "1、大一" << endl;
			cout << "2、大二" << endl;
			cout << "3、大三" << endl;
			cout << "4、大四" << endl;
			cin >> select;
			Student* student = NULL;
			switch (select)
			{
			case 1://大一
				student = new Grade01(newid, newname, 1);
				break;
			case 2://大2
				student = new Grade02(newid, newname, 2);
				break;
			case 3://大3
				student = new Grade03(newid, newname, 3);
				break;
			case 4://大4
				student = new Grade04(newid, newname, 4);
				break;
			default:
				break;
			}
			//更新資料到陣列中
			this->Student_Array[ret] =student;
			cout << "修改成功" << endl;
			//儲存檔案
			this->Save();

		}
		else
		{
			cout << "修改失敗,查無此人" << endl;
		}
		system("pause");
		system("cls");
	}
}

按學號排序

排序採用氣泡排序,前後兩兩比較,根據排序要求進行交換元素位置,達到排序目的

void StudentManager::SortStudent()
{
	if (this->FileIsEmpty)
	{
		cout << "檔案不存在或者記錄為空" << endl;
		system("pause");
		system("cls");

	}
	else
	{
		cout << "請選擇排序方式: " << endl;
		cout << "1、按學號進行升序" << endl;
		cout << "2、按學號進行降序" << endl;

		int select = 0;
		cin >> select;

		for (int i = 0; i < this->Student_Num; i++)
		{
			int minOrmax = i;
			for (int j = i + 1; j < this->Student_Num; j++)
			{
				if (select == 1)
				{
					if (this->Student_Array[minOrmax]->m_id > this->Student_Array[j]->m_id)
					{
						minOrmax = j;
					}
				}
				else
				{
					if (this->Student_Array[minOrmax]->m_id < this->Student_Array[j]->m_id)
					{
						minOrmax = j;
					}
				}
			}
			if (i != minOrmax)
			{
				Student* temp = this->Student_Array[i];
				this->Student_Array[i] = this->Student_Array[minOrmax];
				this->Student_Array[minOrmax] = temp;
			}
		}
		cout << "排序成功" << endl;
		this->Save();	
	}
}

按年級分類檢視

遍歷陣列,匹配相應年級相應程式碼,然後輸出每個年級下面的學生分類

void StudentManager::ClassifyStudent()
{
	cout << "大一:" << endl;
	for (int i = 0; i < this->Student_Num; i++)
	{
		if (this->Student_Array[i]->m_grade == 1)
		{
			this->Student_Array[i]->Show_Info();
			 
		}
	}
	cout << endl;
	cout << "大二:" << endl;
	for (int i = 0; i < this->Student_Num; i++)
	{
		if (this->Student_Array[i]->m_grade ==2)
		{
			this->Student_Array[i]->Show_Info();
			 
		}
	}
	cout << endl;
	cout << "大三:" << endl;
	for (int i = 0; i < this->Student_Num; i++)
	{
		if (this->Student_Array[i]->m_grade == 3)
		{
			this->Student_Array[i]->Show_Info();
			 
		}
	}
	cout << endl;
	cout << "大四:" << endl;
	for (int i = 0; i < this->Student_Num; i++)
	{
		if (this->Student_Array[i]->m_grade ==4)
		{
			this->Student_Array[i]->Show_Info();
		 
		}
	}
	system("pause");
	system("cls");
}

清空資料

首先確認是否清空

然後開啟檔案

開啟模式 ios::trunc 如果存在刪除檔案並重新建立

關閉檔案

判斷,如果指標陣列不為空,那麼將裡面的指標釋放乾淨,成員個數更新為零,將指標陣列置為空,更新檔案為空的標誌。

void StudentManager::CleanStudent()
{
	cout << "確認清空?" << endl;
	cout << "1、確認" << endl;
	cout << "2、返回" << endl;
	int select = 0;
	cin >> select;
	if (select == 1)
	{
		//開啟模式ios::trunc如果存在就刪除檔案並重新建立
		ofstream ofs(FILENAME, ios::trunc);
		ofs.close();
		if (this->Student_Array != NULL)
		{
			for (int i = 0; i < this->Student_Num; i++)
			{
				if (this->Student_Array[i] != NULL)
				{
					delete this->Student_Array[i];
				}
			}
			this->Student_Num = 0;
			delete[] this->Student_Array;
			this->Student_Array = NULL;
			this->FileIsEmpty = true;
		}
		cout << "清空成功" << endl;
	}
	system("pause");
	system("cls");
}

專案程式碼

連結:https://pan.baidu.com/s/1Mo6uVRuZRMmNAYL0bVX8kw
提取碼:s99z

相關文章