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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章