C++學生信息管理系統(含文件流)部分心得含源碼

文件流
C++標準庫頭文件—#include<fstream>,包含:ofstream,ifstream,fstream

open打開文件,close關閉文件
主要注意的是同個文件可同時被打開多次,但是不可以在同個作用域內同時進行IO處理,所以在函數內打開文件並對它處理的時候,記得在最後關閉文件。

ios::in 從文件讀取信息
ios::out 向文件寫入信息
ios::app 所有寫入都追加到文件末尾
ios::trunc 清空文件後打開文件

讀取文件內容一般使用getchar讀取一個字母和getline讀取一行字符串
eof()函數的判斷文件指針是否在最後,故配合eof()可以進行對文件行數的統計等

fstream file(filename,ios::out);
string s;
int row=0;//行數
while(!file.eof())
{
	getline(file,line);
	row++;
}

切記勿直接對文件處理,而是把文件的數據先存儲到計算機中,再對計算機內的容器進行操作。
例如:在學生信息管理系統中需要定義個student的類,我們就可以定義一個vector<student>的數組存儲它;while循環中每次getline一個字符串string後,對字符串進行遍歷,巧妙對空格進行判斷,讓對應的子串賦值給對應的數據,記的留類變量的接口。

friend void read(string filename, vector<student>& a)//文本讀出
	{
		fstream file(filename, ios::in);
		string line;
		getline(file, line);//先讀取文件最頂行的說明保證它不影響數據存儲
		while (!file.eof())
		{
			student* temp = new student;
			string  str = "", s[10];
			int num = 0;
			getline(file, line, '\n');
			for (int i = 0; i < line.size(); i++)
			{
				if ((line[i] == ' ' || line[i] == '\t') && str != "") {
					s[num] = str;
					num++;
					str = "";
				}
				else if (line[i] != ' ' && line[i] != '\t')
					str += line[i];
			}
			s[num] = str;
			if (s[0] != "" && s[1] != "" && s[2] != "" && s[3] != "" && s[4] != "" && s[5] != "" && s[6] != "")
		   {
			temp->SetInformation(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);//學號 姓名 性別 年齡 班級 專業 系別
			a.push_back(*temp);
		   }
			delete temp;
		}
		file.close();
	}
//把修改好的學生信息內容,從vector容器中入讀文本,向文本寫入
	friend void wirte(string filename, vector<student>a)
	{
		fstream file(filename, ios::out | ios_base::trunc);
		file << std::right << "學號" << setw(10) << "姓名" << setw(10) << "性別" << setw(10) << "年齡" << setw(10) << "班級"
			<< setw(10) << "專業" << setw(10) << "系別" << endl;
		for (int i = 0; i < a.size(); i++)
		{
			file << a[i].GetId() << setw(10) << a[i].GetName() << setw(10) << a[i].GetSex() << setw(10)
				<< a[i].GetAge() << setw(10) << a[i].GetClubm() << setw(10) << a[i].GetMajor()
				<< setw(10) << a[i].GetDepartment() << endl;
		}
		file.close();
	}

在對學生信息進行操作管理,
添加,new一個student,最後push_back;

friend void input(vector<student>& a)
	{
		cout << "請輸入學生的學號、姓名、性別(male or female)、年齡、班級、專業、系別(請用空格隔開每個輸入)" << endl;
		student* temp = new student;
		string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
		cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
		temp->SetID(mId); temp->SetName(mName); temp->SetSex(mSex);
		temp->SetAge(mAge); temp->SetMajor(mMajor); temp->SetDepartment(mDepartment);
		a.push_back(*temp);
		delete temp;
		cout <<setw(12)<< "添加成功" << endl;
	}

刪除,先找到要刪除的學生,從這個刪除的學生開始,讓前一名學生等於後一名學生,最後resize讓數組的長度減1;

friend void remove(vector<student>&a, int row)//刪除
	{
		int msize = a.size();
		for (int i = row - 1; i < msize-1; i++)
			a[i] = a[i + 1];
		a.resize(msize - 1);
		cout << setw(10) << "刪除成功" << endl;
	}

修改,先找到要修改的學生,直接對學生信息進行修改,若修改的函數爲爲友元函數,需要定義SetValie()和GetValue()的接口

friend void modify(vector<student>& a, int row)//修改
	{
		cout << "修改人員的完整信息:姓名、性別(male or female)、類別、系別、專業、職稱(請用空格隔開每個輸入)" << endl;
		string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
		cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
		a[row-1].SetID(mId); a[row - 1].SetName(mName); a[row - 1].SetSex(mSex);
		a[row - 1].SetAge(mAge); a[row - 1].SetMajor(mMajor); a[row - 1].SetDepartment(mDepartment);
		cout << "修改成功" << endl;
	}

個人查詢:直接暴力匹配關鍵詞key就行這裏就不演示了

統計:利用map<string,int>統計可以,種類就等於map對應的size(),分別輸出的話直接for遍歷即可,

friend void stat_sex(vector<student>a)//性別統計
	{
		map<string, int>num_sex;
		for (int i = 0; i < a.size(); i++)
			num_sex[a[i].GetSex()]++;
		for (auto it : num_sex)
			cout << setw(10) << it.first << ":" << it.second << endl;
	}

完整源碼無bug如下

// I am so vegetable
//made by HRdate,2020-6-29
#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<string>
#include<iomanip>
#include<set>
#include<map>
#include<conio.h>
using namespace std;
#define endl '\n'

class student
{
public:
	//構造函數
	student() {};
	student(string mid, string mname, string msex, string mage, string mclubm, string mmajor, string mdepartment)
	{
		id = mid, name = mname, sex = msex, age = mage, clubm = mclubm, major = mmajor, department = mdepartment;
	}
	//析構函數
	~student() {};
	//大接口,便於在類外初始化修改類對象的私有變量
	void SetInformation(string mid, string mname, string msex, string mage, string mclubm, string mmajor, string mdepartment)
	{
		id = mid, name = mname, sex = msex, age = mage, clubm = mclubm, major = mmajor, department = mdepartment;
	}
	//小接口,獲取
	string GetId() { return id; }
	string GetName() { return name; }
	string GetSex() { return sex; }
	string GetAge() { return age; }
	string GetClubm() { return clubm; }
	string GetMajor() { return major; }
	string GetDepartment() { return department; }
	//小接口,賦值
	void SetID(string mId) { id = mId; }
	void SetName(string mName) { name = mName; }
	void SetSex(string mSex) { sex = mSex; }
	void SetAge(string mAge) { age = mAge; }
	void SetClubm(string mClubm) { clubm = mClubm; }
	void SetMajor(string mMajor) { major = mMajor; }
	void SetDepartment(string mDepartment) { department = mDepartment; }
	//把文本中的數據轉化爲字符串,通過對字符串空格的處理,使得相應的數據通過SetInformation類接口賦值給vector<student>中的對應的變量
	friend void read(string filename, vector<student>& a)
	{
		fstream file(filename, ios::in | ios::out);
		string line;
		getline(file, line);
		while (!file.eof())
		{
			student temp;
			string  str = "", s[10];
			int num = 0;
			getline(file, line);
			for (int i = 0; i < line.size(); i++)
			{
				if ((line[i] == ' ' || line[i] == '\t') && str != "") {
					s[num] = str;
					num++;
					str = "";
				}
				else if (line[i] != ' ' && line[i] != '\t')
					str += line[i];
			}
			s[num] = str;
			if (s[0] != "" && s[1] != "" && s[2] != "" && s[3] != "" && s[4] != "" && s[5] != "" && s[6] != "")
			{
				temp.SetInformation(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
				a.push_back(temp);
			}
		}
		file.close();
	}
	//把修改好的學生信息內容,從vector容器中入讀文本,向文本寫入
	friend void write(string filename, vector<student>a)
	{
		fstream file(filename, ios::out | ios_base::trunc);
		file << "學號"<<'\t'<< "姓名" << '\t' << "性別" << '\t' << "年齡" << '\t' << "班級"
			<< '\t' << '\t' << "專業" << '\t' << '\t' << "系別" << endl;
		for (int i = 0; i < a.size(); i++)
		{
			file << a[i].GetId() << '\t' << a[i].GetName() << '\t' << a[i].GetSex() << '\t'
				<< a[i].GetAge() << '\t' << a[i].GetClubm() << '\t' << '\t' << a[i].GetMajor()
				<< '\t' << '\t' << a[i].GetDepartment() << endl;
		}
		file.close();
	}
	//輸出顯示選定的人員信息
	friend void display(vector<student>a)
	{
		cout << "學號" << '\t' << "姓名" << '\t' << "性別" << '\t' << "年齡" << '\t' << "班級"
			<< '\t' << '\t' << "專業" << '\t' << '\t' << "系別" << endl;
		for (int i = 0; i < a.size(); i++)
		{
			cout << a[i].GetId() << '\t' << a[i].GetName() << '\t' << a[i].GetSex() << '\t'
				<< a[i].GetAge() << '\t' << a[i].GetClubm() << '\t' << '\t' << a[i].GetMajor()
				<< '\t' << '\t' << a[i].GetDepartment() << endl;
		}
	}
	// I am so vegetable
//made by HRdate,2020-6-29
	//錄入一個學生的信息,new一個student對象,通過SetID等接口可在類外直接定義修改private的成員變量,最後push_back進原容器vector中
	friend void input(vector<student>& a)
	{
		cout << "請輸入學生的完整信息:學號、姓名、性別(男 or 女)、年齡、班級、專業、系別(請用空格隔開每個輸入)" << endl;
		student temp;
		string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
		cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
		temp.SetID(mId), temp.SetName(mName), temp.SetSex(mSex), temp.SetAge(mAge);
		temp.SetClubm(mClubm); temp.SetMajor(mMajor); temp.SetDepartment(mDepartment);
		a.push_back(temp);
		cout << '\t' << '\t' << "添加成功" << endl;
	}
	//刪除指定學生的信息,從這指定的學生開始,讓後一個student賦值給前一個student,往前疊加,最後resize修改一下vector容器大小
	friend void remove(vector<student>&a, int row)//刪除
	{
		int msize = a.size();
		for (int i = row ; i < msize-1; i++)
			a[i] = a[i + 1];
		a.resize(msize - 1);
		cout << '\t' << '\t' << "刪除成功" << endl;
	}
	//修改指定學生的信息
	friend void modify(vector<student>& a, int row)
	{
		cout << "修改學生的完整信息:學號、姓名、性別(男 or 女)、年齡、班級、專業、系別(請用空格隔開每個輸入)" << endl;
		string mId, mName, mSex, mAge, mClubm, mMajor, mDepartment;
		cin >> mId >> mName >> mSex >> mAge >> mClubm >> mMajor >> mDepartment;
		a[row].SetID(mId); a[row].SetName(mName); a[row].SetSex(mSex); a[row].SetAge(mAge);
		a[row ].SetClubm(mClubm);a[row ].SetMajor(mMajor); a[row ].SetDepartment(mDepartment);
		cout << "修改成功" << endl;
	}
	//根據學號查詢個人
	friend int find_id(string key_id, vector<student>a)
	{
		for (int i = 0; i < a.size(); i++)
			if (a[i].GetId() == key_id)
				return i;
	}
	//根據姓名查詢個人
	friend int find_name(string key_name, vector<student>a)
	{
		for (int i = 0; i < a.size(); i++)
			if (a[i].GetName() == key_name)
				return i ;
	}
	//根據性別查詢
	friend void find_key_sex(string key_sex, vector<student>a, vector<student>& b)
	{
		b.clear();
		for (int i = 0; i < a.size(); i++)
		{
			if (a[i].GetSex() == key_sex)
				b.push_back(a[i]);
		}
		//cout << key_sex << "查詢成功" << endl;
	}
	//根據班級查詢
	friend void find_key_clubm(string key_clubm, vector<student>a, vector<student>& b)
	{
		b.clear();
		for (int i = 0; i < a.size(); i++)
		{
			if (a[i].GetClubm() == key_clubm)
				b.push_back(a[i]);
		}
		//cout << key_clubm << "查詢成功" << endl;
	}
	//性別統計
	friend void stat_sex(vector<student>a)
	{
		map<string, int>num_sex;
		for (int i = 0; i < a.size(); i++)
			num_sex[a[i].GetSex()]++;
		for (auto it : num_sex)
			cout << setw(10) << it.first << ":" << it.second << endl;
	}
	//班號統計
	friend void stat_clubm(vector<student>a)
	{
		map<string, int>num_clubm;
		for (int i = 0; i < a.size(); i++)
			num_clubm[a[i].GetClubm()]++;
		for (auto it : num_clubm)
			cout << setw(10) << it.first << ":" << it.second << endl;
	}
	//年齡統計
	friend void stat_age(vector<student>a)
	{
		map<string, int>num_age;
		for (int i = 0; i < a.size(); i++)
			num_age[a[i].GetAge()]++;
		for (auto it : num_age)
			cout << setw(10) << it.first << ":" << it.second << endl;
	}
	//系別統計
	friend void stat_department(vector<student>a)
	{
		map<string, int>num_department;
		for (int i = 0; i < a.size(); i++)
			num_department[a[i].GetDepartment()]++;
		for (auto it : num_department)
			cout << setw(10) << it.first << ":" << it.second << endl;
	}

private:
	string id, name, sex, age, clubm, major, department;//學號 姓名 性別 年齡 班級 專業 系別
};

int main()
{
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	string filename = "E:\\text2.txt";//文件名
	fstream file(filename, ios::in | ios::out);
	if (!file) {
		cout << "打開文件失敗,請重新輸入。" << endl;
		return 0;
	}
	else {
		cout << "打開文件成功。" << endl;
	}
	vector<student>a, b;//vector不定數組存儲數據
	read(filename, a);
	while (1)
	{
		int check = 0;//菜單選擇步驟
		string key;//查詢關鍵詞
		for (int i = 0; i < 70; i++)
			cout << '*';
		cout << endl;
		cout << "*" << setw(32) << "菜單" <<setw(37)<< "*" << endl;
		cout << "*" << setw(40) << "輸入0:退出系統保存" <<setw(29)<<"*" << endl;
		cout << "*" << setw(40) << "輸入1:顯示當前文本" << setw(29) << "*" << endl;
		cout << "*" << setw(40) << "輸入2:刪除學生信息" << setw(29) << "*" << endl;
		cout << "*" << setw(40) << "輸入3:修改學生信息" << setw(29) << "*" << endl;
		cout << "*" << setw(40) << "輸入4:查詢個人信息" << setw(29) << "*" << endl;
		cout << "*" << setw(40) << "輸入5:查詢學生信息" << setw(29) << "*" << endl;
		cout << "*" << setw(40) << "輸入6:統計學生信息" << setw(29) << "*" << endl;
		cout << "*" << setw(40) << "輸入7:添加學生信息" << setw(29) << "*" << endl;
		for (int i = 0; i < 70; i++)
			cout << '*';
		cout << endl;
		cin >> check;
			if (check == 0)//退出系統保存
				break;
			else if (check == 1) {//顯示當前文本
				display(a);
			}
			else if (check == 2) //刪除學生信息
			{
				cout << "1:按學號找到刪除單個學生信息" << endl << "2:按姓名找到刪除單個學生信息" << " (輸入0:退出)" << endl;
				cin >> check;
				if (check == 1)
				{
					cout << "請輸入刪除單個學生的學號:" << endl;
					cin >> key;
					remove(a, find_id(key, a));
				}
				else if (check == 2) {
					cout << "請輸入刪除單個學生的姓名:" << endl;
					cin >> key;
					remove(a, find_name(key, a));
				}
			}
			else if (check == 3)//修改學生信息
			{
				cout << "1:按學號找到修改單個學生信息" << endl << "2:按姓名找到修改單個學生信息" << " (輸入0:退出)" << endl;
				cin >> check;
				if (check == 1)
				{
					cout << "請輸入修改單個學生的學號:" << endl;
					cin >> key;
					modify(a, find_id(key, a));
				}
				else if (check == 2) {
					cout << "請輸入修改單個學生的姓名:" << endl;
					cin >> key;
					modify(a, find_name(key, a));
				}
			}
			else if (check == 4)//查詢個人信息
			{
				cout << "1:按學號查詢單個學生信息" << endl << "2:按姓名找到查詢單個學生信息" << " (輸入0:退出)" << endl;
				cin >> check;
				if (check == 1)
				{
					cout << "請輸入查詢單個學生的學號:" << endl;
					cin >> key;
					vector<student>c;
					c.push_back(a[find_id(key, a) - 1]);
					display(c);
				}
				else if (check == 2) {
					cout << "請輸入查詢單個學生的姓名:" << endl;
					cin >> key;
					vector<student>c;
					c.push_back(a[find_name(key, a) - 1]);
					display(c);
				}
			}
			else if (check == 5)//查詢學生信息
			{
				cout << "1:按性別查詢學生信息" << endl << "2:按班號查詢學生信息" << " (輸入0:退出)" << endl;
				cin >> check;
				if (check == 1)
				{
					cout << "請輸入查詢學生的性別:" << endl;
					cin >> key;
					vector<student>c;
					find_key_sex(key, a, c);
					display(c);
				}
				else if (check == 2)
				{
					cout << "請輸入查詢學生的班號:" << endl;
					cin >> key;
					vector<student>c;
					find_key_clubm(key, a, c);
					display(c);
				}
			}
			else if (check == 6)//統計學生信息
			{
				cout << "1:按性別統計學生人數" << endl << "2:按班別統計學生人數" << endl << "3:按年齡統計學生人數" << endl
					<< "4:按系別統計學生人數" <<endl<< " (輸入0:退出)" << endl;
				cin >> check;
				if (check == 1)
				{
					stat_sex(a);
				}
				else if (check == 2)
				{
					stat_clubm(a);
				}
				else if (check == 3)
				{
					stat_age(a);
				}
				else if (check == 4)
				{
					stat_department(a);
				}
			}
			else if (check == 7)//添加學生信息
			{
				input(a);
			}
			//getchar();
			// system("cls"); 清屏
	}
	write(filename, a);
	file.close();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章