C++面向对象程序设计——学生管理系统(2.8万字匠心之作,内含文件压缩包及源码)

syf:C++面向对象程序设计有什么作用吗?

shy:C++的面向对象程序设计有封装、继承、多态、抽象、代码重用、模块化开发、增强可维护性和可扩展性等特征,使得软件开发更为灵活、可维护。

hwjw:那么学生管理系统有什么作用吗?

shy:该学生管理系统改编自黑马程序员职工管理系统,能基本实现学校成员的增删改查功能,提高了信息的透明度和管理的效率,有助于提升学校的整体运作水平。

文章目录

1. 学生管理系统使用说明

学生管理系统可以用来管理学院内所有成员信息

本课程设计主要利用C++来实现一个基于多态的学生管理系统

学院中成员分为三类:学生、教师、院长,显示信息时,需要显示成员学号/工号、成员姓名、成员岗位、以及职责

学生职责:完成老师留的小游戏作业

教师职责:完成院长交给的教学任务,并给学生留好结课作业

院长职责:管理学院所有事务

学生管理系统中实现的功能如下:

  • 退出管理系统:退出当前管理系统
  • 增加成员信息:实现批量增加成员的功能,将信息录入到文件中,成员信息为:成员学号/工号、姓名、成员身份
  • 显示成员信息:显示学院内部所有成员信息
  • 删除成员信息:按照学号/工号删除指定成员
  • 修改成员信息:按照学号/工号修改成员个人信息
  • 查找成员信息:按照成员的学号/工号或者成员的姓名进行查找相关人员的信息
  • 按照编号排序:按照成员学号/工号,进行排序,可升序也可降序
  • 清空所有文档:清空文件记录的所有成员信息,清空前需确认防止误删

学生管理系统界面效果图:

学生管理系统效果图

2. 创建学生管理系统源文件

具体代码如下:

#include"studentManager.h"
#include<iostream>
using namespace std;


int main()
{
	//实例化管理者对象
	StudentManager sm;
	
	int choice ; //存储用户

	while (true)
	{
		//调用展示菜单成员函数
		sm.Show_Menu();

		cout << "请输入您的选择: \n";
		cin >> choice;//接受用户选项

		switch (choice)
		{
		case 0: //退出系统
			sm.ExitSystem();
			break;
		case 1: //增加成员
			sm.Add_Stu();
			break;
		case 2: //显示成员
			sm.Show_Stu();
			break;
		case 3: //删除成员
		//{
		//	//测试
		//	int ret = sm.IsExist(202222450410);
		//	if (ret != -1)
		//	{
		//		cout << "成员存在" << endl;
		//	}
		//	else
		//	{
		//		cout << "成员不存在" << endl;
		//	}
		//	break;
		//}
			sm.Del_Stu();
			break;
		case 4: //修改成员
			sm.Mod_Stu();
			break;
		case 5: //查找成员
			sm.Find_Stu();
			break;
		case 6: //排序成员
			sm.Sort_Stu();
			break;
		case 7: //清空文档
			sm.Clean_File();
			break;
		default:
			system("cls"); //清屏
			break;
		}
	}
	//调用展示菜单成员函数
	sm.Show_Menu();

	system("pause");

	return 0;
}

3. 创建管理类

管理类负责内容:

  • 与用户的沟通菜单界面
  • 对成员增删改查的操作
  • 与文件的读写交互

3.1 创建文件

头文件创建:studentManager.h 源文件创建:studentManager.cpp

3.2 头文件

在studentManager.h中设计管理类

#pragma once  //防止头文件重复包含
#include<iostream>
using namespace std;

class StudentManager
{
public:
    //构造函数
	StudentManager();
	//析构函数
	~StudentManager();
};

3.3 源文件

在studentManager.cpp中将构造和析构函数空实现补全

#include"studentManager.h"

StudentManager::StudentManager()
{
    
}
StudentManager::~StudentManager()
{
    
}

4. 菜单功能

功能描述:与用户的沟通界面

4.1 添加成员函数

在管理类studentManager.h中添加成员函数

void Show_Menu();

4.2 菜单功能实现

在管理类studentManager.cpp中实现 Show_Menu()函数

void StudentManager::Show_Menu()
{
	cout << "____________________________________________\n";
	cout << "|                                          |\n";
	cout << "|           欢迎使用学生管理系统!         |\n";
	cout << "|              0.退出管理系统              |\n";
	cout << "|              1.增加成员信息              |\n";
	cout << "|              2.显示成员信息              |\n";
	cout << "|              3.删除成员信息              |\n";
	cout << "|              4.修改成员信息              |\n";
	cout << "|              5.查找成员信息              |\n";
	cout << "|              6.按照编号排序              |\n";
	cout << "|              7.清空所有文档              |\n";
	cout << "|__________________________________________|\n\n";
}

4.3 菜单功能测试

在学生管理系统.cpp中测试菜单功能

#include<iostream>
#include"studentManager.h"
using namespace std;

int main()
{
    //实例化管理者对象
	StudentManager sm;
    //调用展示菜单成员函数
	sm.Show_Menu();
    system("pause");
    return 0;
}

运行效果如图

菜单效果图

5. 退出功能

5.1 退出功能接口

在main()函数中提供分支选择,提供每个功能接口

int main()
{
	//实例化管理者对象
	StudentManager sm;
	
	int choice ; //存储用户

	while (true)
	{
		//调用展示菜单成员函数
		sm.Show_Menu();

		cout << "请输入您的选择: \n";
		cin >> choice;//接受用户选项

		switch (choice)
		{
		case 0: //退出系统
             sm.ExitSystem();
			break;
		case 1: //增加成员
			break;
		case 2: //显示成员
			break;
		case 3: //删除成员
			break;
		case 4: //修改成员
			break;
		case 5: //查找成员
			break;
		case 6: //排序成员
			break;
		case 7: //清空文档
			break;
		default:
			system("cls"); //清屏
			break;
		}
	}

	system("pause");

	return 0;
}

5.2 实现退出功能

在studentManager.h中提供退出系统的成员函数 void exitSystem();

在studentManager.cpp中提供具体的功能实现

void StudentManager::ExitSystem()
{
	cout << "欢迎下次使用\n";
	system("pause");
	exit(0); //退出程序
}

5.3 功能测试

在main()函数分支0的选项中,调用退出程序的接口

运行效果:

退出功能效果

6. 创建成员类

6.1 创建成员抽象类

成员的分类为:学生、老师、院长

将三种成员抽象到一个类(member)中,利用多态管理不同的成员类型

成员属性:成员学号/工号、成员姓名、成员身份

成员行为:身份职责信息描述,获取身份

头文件文件夹下 创建文件 member.h 文件并添加如下代码:

#pragma once
#include<iostream>
using namespace std;
#include<string>

//成员抽象类
class Member
{
public:

	//显示个人信息
	virtual void showInfo()=0;

	//获取身份名称
	virtual string getDeptName()=0 ;

	//成员工号、学号
	long long m_Id;
	//成员姓名
	string m_Name;
	//身份编号
	int m_DeptId;
};

6.2 创建学生类

学生类继承成员抽象类,并重写父类中纯虚函数

在头文件和源文件的文件夹下分别创建student.h和student.cpp文件

student.h中代码如下:

#pragma once
#include<iostream>
using namespace std;
#include"member.h"

class Student :public Member
{
public:

	//构造函数
	Student(long long id,string name,int dId);

	//显示个人信息
	virtual void showInfo();

	//获取身份名称
	virtual string getDeptName();
};

student.cpp中代码如下:

#include"student.h"

//构造函数
Student::Student(long long id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

//显示个人信息
void Student::showInfo()
{
	cout << "成员学号/工号:" << this->m_Id << "\t成员姓名:" << this->m_Name << "\t成员身份:" << this->getDeptName() << "\t成员职责:完成老师留的小游戏作业\n";
}

//获取身份信息
string Student::getDeptName()
{
	return string("学生");
}

6.3 创建教师类

教师类继承成员抽象类,并重写父类中纯虚函数,和学生类似

在头文件和源文件的文件夹下分别创建teacher.h和teacher.cpp文件

teacher.h中代码如下:

#pragma once
#include<iostream>
using namespace std;
#include"member.h"

//教师类
class Teacher :public Member
{
public:

	//构造函数
	Teacher(long long id, string name, int dId);

	//显示个人信息
	virtual void showInfo();

	//获取身份名称
	virtual string getDeptName();

};

teacher.cpp中代码如下:

#include"teacher.h"

//构造函数
Teacher::Teacher(long long id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

//显示个人信息
void Teacher::showInfo()
{
	cout << "成员学号/工号:" << this->m_Id << "\t成员姓名:" << this->m_Name << "\t成员身份:" << this->getDeptName() << "\t成员职责:完成院长交给的教学任务,并给学生留好结课作业\n";
}

//获取身份名称
string Teacher::getDeptName()
{
	return string("教师");
}

6.4 创建院长类

院长类继承成员抽象类,并重写父类中纯虚函数,和学生类似

在头文件和源文件的文件夹下分别创建dean.h和dean.cpp文件

dean.h中代码如下:

#pragma once
#include<iostream>
using namespace std;
#include"member.h"

//院长类
class Dean :public Member
{
public:

	//构造函数
	Dean(long long id, string name, int dId);

	//显示个人信息
	virtual void showInfo();

	//获取身份名称
	virtual string getDeptName();

};

dean.cpp中代码如下:

#include"dean.h"

//构造函数
Dean::Dean(long long id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

//显示个人信息
void Dean::showInfo()
{
	cout << "成员学号/工号:" << this->m_Id << "\t成员姓名:" << this->m_Name << "\t成员身份:" << this->getDeptName() << "\t成员职责:管理学院所有事务\n";
}

//获取身份名称
string Dean::getDeptName()
{
	return string("院长");
}

7. 添加成员

功能描述:批量添加成员,并且保存到文件中

7.1 功能分析

用户在批量创建时,可能会创建不同种类成员

如果想将所有不同类型的成员都放到一个数组中,可以将所有成员的指针维护到一个数组里

如果想要在程序中维护这个不定长度的数组,可以将数组创建到堆区,利用Member**的指针维护

7.2 功能实现

在studentManager.h的头文件中添加成员属性:

	//记录成员人数
	int m_StuNum;
	//学生数组指针
	Member** m_StuArray;

在studentManager.cpp构造函数中初始化属性:

StudentManager::StudentManager()
{
	//初始化记录人数
	this->m_StuNum = 0;
	//初始化数组指针
	this->m_StuArray = NULL;
}

在studentManager.h中添加成员函数

	//添加成员
	void Add_Stu();

studentManager.cpp中实现该函数

//添加成员
void StudentManager::Add_Stu()
{
	cout << "请输入添加学生数量:" << endl;

	int addNum = 0; //保存用户输入数量
	cin >> addNum;

	if (addNum > 0)
	{
		//添加
		//计算添加新空间大小
		//新空间人数=原来记录人数+新增人数
		int newSize = this->m_StuNum + addNum;

		//开辟新空间
		Member ** newSpace = new Member* [newSize];

		//将原来空间下数据,拷贝到新空间下
		{
			if (this->m_StuArray != NULL)
			{
				for (int i = 0; i < this->m_StuNum; i++)
				{
					newSpace[i] = this->m_StuArray[i];
				}
			}
		}

		//批量添加新数据
		for (int i = 0; i < addNum; i++)
		{
			long long id; //成员编号
			string name; //成员姓名
			int dSelect; //身份选择

			cout << "请输入第 " << i + 1 << " 个新成员编号: " << endl;
			cin >> id;

			cout << "请输入第 " << i + 1 << " 个新成员姓名: " << endl;
			cin >> name;

			cout << "请选择该成员身份: " << endl;
			cout << "1.学生" << endl;
			cout << "2.老师" << endl;
			cout << "3.院长" << endl;
			cin >> dSelect;

			Member* member = NULL;
			switch (dSelect)
			{
			case 1:
				member = new Student(id, name, 1);
				break;
			case 2:
				member = new Teacher(id, name, 2);
				break;
			case 3:
				member = new Dean(id, name, 3);
				break;
			default:
				break;
			}
			//将创建成员职责,保存到数组中
			newSpace[this->m_StuNum + i] = member;
		}

		//释放原有的空间
		delete[] this->m_StuArray;

		//更改新空间指向
		this->m_StuArray = newSpace;

		//更新新成员人数
		this->m_StuNum = newSize;

		//更新成员不为空
		this->m_FileIsEmpty = false;

		//提示添加成功
		cout << "成功添加" << addNum << "名新成员!" << endl;

		//保存数据到文件中
		this->save();
	}
	else
	{
		cout << "输入数据有误!" << endl;
	}

	//按任意键后 清屏回到上级目录
	system("pause");
	system("cls");
}

7.3 添加功能测试

添加功能效果

8. 文件交互

8.1 写文件

8.1.1 设定文件路径

将文件路径,在studentManager.h中添加宏常量,并且包含头文件fstream

#include<fstream>
#define FILENAME "成员名单.txt"
8.1.2 成员函数声明

在studentManager.h中类里添加成员函数void save()

	//保存文件
	void save();
8.1.3 保存文件功能实现
//保存文件
void StudentManager::save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out); //输出方式打开文件 ——写文件

	//将每个人数据写入文件中
	for (int i = 0; i < this->m_StuNum; i++)
	{
		ofs << this->m_StuArray[i]->m_Id << " " << this->m_StuArray[i]->m_Name << " " << this->m_StuArray[i]->m_DeptId << endl;
	}

	//关闭文件
	ofs.close();
}
8.1.4 保存文件功能测试

在添加成员功能中添加成功后添加保存文件函数

	//保存到文件中
	this->save();

进行一次添加操作:

添加操作

同级目录多出文件,并保存了添加的信息

文件内保存了添加的信息

8.2 读文件

功能描述:将文件中的内容读到程序中

构造函数初始化数据情况分三种:

1.第一次使用,文件未创建

2.文件存在,但是数据被用户清空

3.文件存在,并保存成员所有数据

8.2.1 文件未创建

在studentManager.h中添加新成员属性m_FileIsEmpty标志文件是否为空

	//判断文件是否为空
	bool m_FileIsEmpty;

studentManager.cpp中构造函数代码

StudentManager::StudentManager()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in); //读文件

	if (!ifs.is_open())
	{
		//cout << "文件不存在!" << endl;
		//初始化属性
		//初始化记录人数
		this->m_StuNum = 0;
		//初始化数组指针
		this->m_StuArray = NULL;
		//初始化文件是否为空
		this->m_FileIsEmpty = true;
		ifs.close();
		return;
	}
}
8.2.2 文件存在数据为空

在studentManager.cpp中的构造函数追加代码:

StudentManager::StudentManager()
{
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		//文件为空
		//cout << "文件为空!" << endl;
		//初始化记录人数
		this->m_StuNum = 0;
		//初始化数组指针
		this->m_StuArray = NULL;
		//初始化文件是否为空
		this->m_FileIsEmpty = true;
		ifs.close();
		return;
	}
}
8.2.3 文件存在且保存成员数据
8.2.3.1 获取记录的成员人数

在studentManager.h中添加成员函数int get_StuNum();

	//统计文件中人数
	int get_StuNum();

studentManager.cpp中实现

int StudentManager::get_StuNum()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in); //打开文件 读

	long long id;
	string name;
	int dId;

	int num = 0;
	while (ifs >> id && ifs >> name && ifs >> dId)
	{
		//统计人数变量
		num++;
	}

	return num;
}

在studentManager.cpp构造函数中追加代码:

	int num = this->get_StuNum();
	this->m_StuNum = num;
8.2.3.2 初始化数组

根据成员的数据,初始化studentManager中的Member**m_StuArray指针

在studentManager.h中添加成员函数 void init_Stu();

	//初始化成员
	void init_Stu();

在studentManager.cpp中实现

void StudentManager::init_Stu()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	long long id;
	string name;
	int dId;

	int index = 0;
	while (ifs >> id && ifs >> name && ifs >> dId)
	{
		Member * member = NULL;

		if (dId == 1) //学生
		{
			member = new Student(id, name, dId);
		}
		else if (dId == 2) //老师
		{
			member = new Teacher(id, name, dId);
		}
		else //院长
		{
			member = new Dean(id, name, dId);
		}
		this->m_StuArray[index] = member;
		index++;
	}

	//关闭文件
	ifs.close();
}

在studentManager.cpp构造函数中追加代码:

	//开辟空间
	this->m_StuArray = new Member * [this->m_StuNum];
	//将文件中的数据存到数组中
	this->init_Stu();

9. 显示成员

功能描述:显示当前所有成员信息

9.1 显示成员函数声明

在studentManager.h中添加成员函数 void Show_Stu();

	//显示成员
	void Show_Stu();

9.2 显示成员函数实现

在studentManager.cpp中实现成员函数 void Show_Stu();

void StudentManager::Show_Stu()
{
	//判断文件是否为空
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		for (int i = 0; i < m_StuNum; i++)
		{
			//利用多态调用程序接口
			this->m_StuArray[i]->showInfo();
		}
	}
	//按任意键后清屏
	system("pause");
	system("cls");

}

9.3 测试显示成员

在main()函数分支2选项中,调用显示成员接口

		case 2: //显示成员
			sm.Show_Stu();
			break;

测试文件不存在或者为空:

测试文件不存在或者为空

文件存在且有记录:

文件存在且有记录

10. 删除成员

功能描述:按照成员编号进行删除成员操作

10.1 删除成员函数声明

在studentManager.h中添加成员函数 void Del_Stu();

	//删除成员
	void Del_Stu();

10.2 成员是否存在函数声明

添加公告函数,以便后续调用

在studentManager.h中添加成员函数 int IsExist(long long id);

//判断成员是否存在 如果存在返回成员所在数组中的位置,不存在返回-1
	int IsExist(long long id);

10.3 成员是否存在函数实现

在studentManager.cpp中实现成员函数 int IsExist(long long id);

//判断成员是否存在 如果存在返回成员所在数组中的位置,不存在返回-1
int StudentManager::IsExist(long long id)
{
	int index = -1;

	for (int i = 0; i < this->m_StuNum; i++)
	{
		if (this->m_StuArray[i]->m_Id == id)
		{
			//找到成员
			index = i;

			break;
		}
	}
	return index;
}

10.4 删除成员函数实现

在studentManager.cpp中实现成员函数 void Del_Stu();

void StudentManager::Del_Stu()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		//按照学号/工号删除
		cout << "请输入想要删除职工的编号:" << endl;
		long long id = 0;
		cin >> id;
		int index = this->IsExist(id);
		if (index != -1) //说明成员存在,并且要删除掉index位置上的成员
		{
			
			for (int i = index; i < this->m_StuNum - 1; i++)
			{
				//数据前移
				this->m_StuArray[i] = this->m_StuArray[i + 1];
			}
			this->m_StuNum--; //更新数组中记录成员个数
			//同步更新到文件中
			this->save();

			cout << "删除成功!" << endl;
		}
		else
		{
			cout << "删除失败,未找到该成员" << endl;
		}
	}

	//按任意键清屏
	system("pause");
	system("cls");
}

10.5 测试删除成员

在main()函数分支3选项中,调用删除成员接口

	case 3:
		sm.Del_Stu();
		break;

删除不存在成员的情况

删除不存在成员

删除存在的成员情况

删除存在的成员

再次显示所有成员信息,确保已经删除

显示成员信息

查看文件中的信息,核实成员已被完全删除

核实文件中的信息

11. 修改成员

功能描述:能够按照成员的编号对成员信息进行修改并保存

11.1 修改成员函数声明

在studentManager.h中添加成员函数 void Mod_Stu();

	//修改成员
	void Mod_Stu();

11.2 修改成员函数实现

在studentManager.cpp中实现成员函数 void Mod_Stu();

//修改成员
void StudentManager::Mod_Stu()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入修改成员学号/工号:" << endl;
		long long id;
		cin >> id;
		int ret = this->IsExist(id);
		if (ret != -1)
		{
			//查找到学号/工号的成员
			delete this->m_StuArray[ret];

			long long newId = 0;
			string newName = "";
			int dSelect = 0;

			cout << "查到:" << id << "号成员,请输入新成员学号/工号:" << endl;
			cin >> newId;

			cout << "请输入新姓名:" << endl;
			cin >> newName;

			cout << "请输入新身份:" << endl;
			cout << "1、学生" << endl;
			cout << "2、老师" << endl;
			cout << "3、院长" << endl;

			cin >> dSelect;

			Member* member = NULL;
			switch (dSelect)
			{
			case 1:
				member = new Student(newId, newName, dSelect);
				break;
			case 2:
				member = new Teacher(newId, newName, dSelect);
				break;
			case 3:
				member = new Dean(newId, newName, dSelect);
				break;
			default:
				break;
			}

			//更新数据到数组中
			this->m_StuArray[ret] = member;

			cout << "修改成功!" << endl;

			//保存到文件中
			this->save();
		}
		else
		{
			cout << "修改失败,查无此人!" << endl;
		}
	}

	//按任意键按清屏
	system("pause");
	system("cls");
}

12. 查找成员

功能描述:提供两种查找成员方式,一种按照成员学号/工号,一种按照成员姓名

12.1 查找成员函数声明

在studentManager.h中添加成员函数 void Find_Stu();

	//查找成员
	void Find_Stu();

12.2 查找成员函数实现

在studentManager.cpp中实现成员函数 void Find_Stu();

void StudentManager::Find_Stu()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入查找的方式:" << endl;
		cout << "1、按成员学号/工号查找 " << endl;
		cout << "2、按成员姓名查找 " << endl;

		int select = 0;
		cin >> select;

		if (select == 1)
		{
			//按照编号查
			long long id;
			cout << "请输入查找的成员学号/工号:" << endl;
			cin >> id;

			int ret = IsExist(id);
			if (ret != -1)
			{
				//找到成员
				cout << "查找成功!该成员信息如下:" << endl;
				this->m_StuArray[ret]->showInfo();
			}
			else
			{
				cout << "查找失败,查无此人" << endl;
			}
		}
		else if (select == 2)
		{
			//按照姓名查
			string name;
			cout << "请输入查找的姓名:" << endl;
			cin >> name;

			//加入判断是否查到标志
			bool flag = false; //默认未找到成员
			
			for (int i = 0; i < m_StuNum; i++)
			{
				if (this->m_StuArray[i]->m_Name == name)
				{
					cout << "查找成功,成员学号/工号为:" << this->m_StuArray[i]->m_Id << "号成员信息如下:" << endl;

					flag = true;
					//调用显示信息接口
					this->m_StuArray[i]->showInfo();
				}
			}
			if (flag == false)
			{
				cout << "查找失败,查无此人!" << endl;
			}
		}
		else
		{
			cout << "输入选项有误!" << endl;
		}
	}

	//按任意键清屏
	system("pause");
	system("cls");
}

12.3 测试查找成员

在main()函数分支5选项中,调用查找成员接口

	case 5: //查找成员
		sm.Find_Stu();
		break;

按照成员学号/工号查找,查找不存在成员

按学号查找不存在

按照成员学号/工号查找,查找存在成员

按学号查找存在

按照成员姓名查找,查找不存在成员

按姓名查找不存在

按照成员姓名查找,查找存在成员(如果出现重名,也一并显示,在文件中可以添加重名成员)

例如:有两名成员都叫孙华艺,按照姓名查找孙华艺

成员重名

按姓名查找出现重名

13. 排序

功能描述:按照成员学号/工号进行排序,排序的顺序由用户指定

13.1 排序函数声明

在studentManager.h中添加成员函数 void Sort_Stu();

	//按照学号/工号排序
	void Sort_Stu();

13.2 排序函数实现

在studentManager.cpp中实现成员函数 void Sort_Stu();

void StudentManager::Sort_Stu()
{
	if (this->m_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 < m_StuNum; i++)
		{
			int minOrMax = i; //声明最小值或最大值下标
			for (int j = i + 1; j < this->m_StuNum; j++)
			{
				if (select == 1) //升序
				{
					if (this->m_StuArray[minOrMax]->m_Id > this->m_StuArray[j]->m_Id)
					{
						minOrMax = j;
					}
				}
				else //降序
				{
					if (this->m_StuArray[minOrMax]->m_Id < this->m_StuArray[j]->m_Id)
					{
						minOrMax = j;
					}
				}
			}

			//判断一开始认定的 最小值或最大值 是不是 计算的最小值或最大值,如果不是 交换数据
			if (i != minOrMax)
			{
				Member* temp = this->m_StuArray[i];
				this->m_StuArray[i] = this->m_StuArray[minOrMax];
				this->m_StuArray[minOrMax] = temp;
			}
		}
		cout << "排序成功!排序后的结果为:" << endl;
		//this->save(); //排序后结果保存到文件中,可存可不存,看需求
		this->Show_Stu(); //展示所有成员
	}
}

13.3 测试排序功能

在main()函数分支6选项中,调用排序成员接口

	case 6: //排序成员
		sm.Sort_Stu();
		break;

首先我们添加一些成员,序号是无序的

添加一些成员

升序排序

升序排序

文件同步更新

文件同步更新

降序排序

降序排序

文件同步更新

文件同步更新

14. 清空文件

功能描述:将文件中记录数据清空

14.1 清空函数声明

在studentManager.h中添加成员函数 void Clean_File();

	//清空文件
	void Clean_File();

14.2 清空函数实现

在studentManager.cpp中实现成员函数 void Clean_File();

void StudentManager::Clean_File()
{
	cout << "确定清空?" << endl;
	cout << "1、确定" << endl;
	cout << "2、返回" << endl;

	int select = 0;
	cin >> select;
	if (select == 1)
	{
		//清空文件
		ofstream ofs(FILENAME, ios::trunc); //删除文件后重新创建
		ofs.close();

		if (this->m_StuArray != NULL)
		{
			//删除堆区的每个成员对象
			for (int i = 0; i < this->m_StuNum; i++)
			{
				delete this->m_StuArray[i];
				this->m_StuArray[i] = NULL;
			}

			//删除堆区的数组指针
			delete[] this->m_StuArray;
			this->m_StuArray = NULL;
			this->m_StuNum = 0;
			this->m_FileIsEmpty = true;
		}
		cout << "清空成功!" << endl;
	}

	system("pause");
	system("cls");
}

14.3 测试清空文件

在main()函数分支7选项中,调用清空文件接口

		case 7: //清空文档
			sm.Clean_File();
			break;

确认清空文件

确认清空文件

再次查看文件中的数据,记录已为空

再次查看记录为空

打开文件,里面的数据已确保清空,该功能需慎用!

查看文件中的数据,记录为空

15. 全部代码展示

15.1 studentManager.h

#pragma once  //防止头文件重复包含
#include<iostream>
#include<algorithm>
#include"member.h"
#include"student.h"
#include"teacher.h"
#include"dean.h"

#include<fstream>
#define FILENAME "成员名单.txt"

using namespace std;

class StudentManager
{
public:

	//构造函数
	StudentManager();

	//展示菜单
	void Show_Menu();

	//退出系统
	void ExitSystem();

	//记录成员人数
	int m_StuNum;

	//学生数组指针
	Member** m_StuArray;

	//添加成员
	void Add_Stu();

	//保存文件
	void save();

	//判断文件是否为空
	bool m_FileIsEmpty;

	//统计文件中人数
	int get_StuNum();

	//初始化成员
	void init_Stu();

	//显示成员
	void Show_Stu();

	//删除成员
	void Del_Stu();

	//判断成员是否存在 如果存在返回成员所在数组中的位置,不存在返回-1
	int IsExist(long long id);

	//修改成员
	void Mod_Stu();

	//查找成员
	void Find_Stu();
	
	//按照学号/工号排序
	void Sort_Stu();

	//清空文件
	void Clean_File();

	//析构函数
	~StudentManager();

};

15.2 member.h

#pragma once
#include<iostream>
using namespace std;
#include<string>

//成员抽象类
class Member
{
public:

	//显示个人信息
	virtual void showInfo()=0;

	//获取身份名称
	virtual string getDeptName()=0 ;

	//成员工号、学号
	long long m_Id;
	//成员姓名
	string m_Name;
	//身份编号
	int m_DeptId;
};

15.3 student.h

#pragma once
#include<iostream>
using namespace std;
#include"member.h"

class Student :public Member
{
public:

	//构造函数
	Student(long long id,string name,int dId);

	//显示个人信息
	virtual void showInfo();

	//获取身份名称
	virtual string getDeptName();
};

15.4 teacher.h

#pragma once
#include<iostream>
using namespace std;
#include"member.h"

//教师类
class Teacher :public Member
{
public:

	//构造函数
	Teacher(long long id, string name, int dId);

	//显示个人信息
	virtual void showInfo();

	//获取身份名称
	virtual string getDeptName();

};

15.5 dean.h

#pragma once
#include<iostream>
using namespace std;
#include"member.h"

//院长类
class Dean :public Member
{
public:

	//构造函数
	Dean(long long id, string name, int dId);

	//显示个人信息
	virtual void showInfo();

	//获取身份名称
	virtual string getDeptName();

};

15.6 studentManager.cpp

#include"studentManager.h"

StudentManager::StudentManager()
{

	//1、文件不存在
	ifstream ifs;
	ifs.open(FILENAME, ios::in); //读文件

	if (!ifs.is_open())
	{
		//cout << "文件不存在!" << endl;
		//初始化属性
		//初始化记录人数
		this->m_StuNum = 0;
		//初始化数组指针
		this->m_StuArray = NULL;
		//初始化文件是否为空
		this->m_FileIsEmpty = true;
		ifs.close();
		return;
	}

	//2、文件存在 数据为空
	char ch;
	ifs >> ch;
	if (ifs.eof())
	{
		//文件为空
		//cout << "文件为空!" << endl;
		//初始化记录人数
		this->m_StuNum = 0;
		//初始化数组指针
		this->m_StuArray = NULL;
		//初始化文件是否为空
		this->m_FileIsEmpty = true;
		ifs.close();
		return;
	}

	//3、文件存在,并且记录数据
	int num = this->get_StuNum();
	//测试test
	//cout << "成员人数为: " << num << endl;
	this->m_StuNum = num;

	//开辟空间
	this->m_StuArray = new Member * [this->m_StuNum];
	//将文件中的数据存到数组中
	this->init_Stu();

	//测试test
	//for (int i = 0; i < this->m_StuNum; i++)
	//{
	//	cout << "成员学号/工号:" << this->m_StuArray[i]->m_Id << "  姓名:" << this->m_StuArray[i]->m_Name << "  成员身份:" << this->m_StuArray[i]->m_DeptId << endl;
	//}
}
//展示菜单
void StudentManager::Show_Menu()
{
	cout << "____________________________________________\n";
	cout << "|                                          |\n";
	cout << "|           欢迎使用学生管理系统!         |\n";
	cout << "|              0.退出管理系统              |\n";
	cout << "|              1.增加成员信息              |\n";
	cout << "|              2.显示成员信息              |\n";
	cout << "|              3.删除成员信息              |\n";
	cout << "|              4.修改成员信息              |\n";
	cout << "|              5.查找成员信息              |\n";
	cout << "|              6.按照编号排序              |\n";
	cout << "|              7.清空所有文档              |\n";
	cout << "|__________________________________________|\n\n";
}

//退出系统
void StudentManager::ExitSystem()
{
	cout << "欢迎下次使用\n";
	system("pause");
	exit(0); //退出程序
}

//添加学生
void StudentManager::Add_Stu()
{
	cout << "请输入添加学生数量:" << endl;

	int addNum = 0; //保存用户输入数量
	cin >> addNum;

	if (addNum > 0)
	{
		//添加
		//计算添加新空间大小
		//新空间人数=原来记录人数+新增人数
		int newSize = this->m_StuNum + addNum;

		//开辟新空间
		Member ** newSpace = new Member* [newSize];

		//将原来空间下数据,拷贝到新空间下
		{
			if (this->m_StuArray != NULL)
			{
				for (int i = 0; i < this->m_StuNum; i++)
				{
					newSpace[i] = this->m_StuArray[i];
				}
			}
		}

		//批量添加新数据
		for (int i = 0; i < addNum; i++)
		{
			long long id; //成员编号
			string name; //成员姓名
			int dSelect; //身份选择

			cout << "请输入第 " << i + 1 << " 个新成员编号: " << endl;
			cin >> id;

			cout << "请输入第 " << i + 1 << " 个新成员姓名: " << endl;
			cin >> name;

			cout << "请选择该成员身份: " << endl;
			cout << "1.学生" << endl;
			cout << "2.老师" << endl;
			cout << "3.院长" << endl;
			cin >> dSelect;

			Member* member = NULL;
			switch (dSelect)
			{
			case 1:
				member = new Student(id, name, 1);
				break;
			case 2:
				member = new Teacher(id, name, 2);
				break;
			case 3:
				member = new Dean(id, name, 3);
				break;
			default:
				break;
			}
			//将创建成员职责,保存到数组中
			newSpace[this->m_StuNum + i] = member;
		}

		//释放原有的空间
		delete[] this->m_StuArray;

		//更改新空间指向
		this->m_StuArray = newSpace;

		//更新新成员人数
		this->m_StuNum = newSize;

		//更新成员不为空
		this->m_FileIsEmpty = false;

		//提示添加成功
		cout << "成功添加" << addNum << "名新成员!" << endl;

		//保存数据到文件中
		this->save();
	}
	else
	{
		cout << "输入数据有误!" << endl;
	}

	//按任意键后 清屏回到上级目录
	system("pause");
	system("cls");
}

//保存文件
void StudentManager::save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out); //输出方式打开文件 ——写文件

	//将每个人数据写入文件中
	for (int i = 0; i < this->m_StuNum; i++)
	{
		ofs << this->m_StuArray[i]->m_Id << " " << this->m_StuArray[i]->m_Name << " " << this->m_StuArray[i]->m_DeptId << endl;
	}

	//关闭文件
	ofs.close();
}

//统计文件中人数
int StudentManager::get_StuNum()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in); //打开文件 读

	long long id;
	string name;
	int dId;

	int num = 0;
	while (ifs >> id && ifs >> name && ifs >> dId)
	{
		//统计人数变量
		num++;
	}

	return num;
}

//初始化成员
void StudentManager::init_Stu()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	long long id;
	string name;
	int dId;

	int index = 0;
	while (ifs >> id && ifs >> name && ifs >> dId)
	{
		Member * member = NULL;

		if (dId == 1) //学生
		{
			member = new Student(id, name, dId);
		}
		else if (dId == 2) //老师
		{
			member = new Teacher(id, name, dId);
		}
		else //院长
		{
			member = new Dean(id, name, dId);
		}
		this->m_StuArray[index] = member;
		index++;
	}

	//关闭文件
	ifs.close();
}

//显示成员
void StudentManager::Show_Stu()
{
	//判断文件是否为空
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		for (int i = 0; i < m_StuNum; i++)
		{
			//利用多态调用程序接口
			this->m_StuArray[i]->showInfo();
		}
	}
	//按任意键后清屏
	system("pause");
	system("cls");

}

//删除成员
void StudentManager::Del_Stu()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		//按照学号/工号删除
		cout << "请输入想要删除职工的编号:" << endl;
		long long id = 0;
		cin >> id;
		int index = this->IsExist(id);
		if (index != -1) //说明成员存在,并且要删除掉index位置上的成员
		{
			
			for (int i = index; i < this->m_StuNum - 1; i++)
			{
				//数据前移
				this->m_StuArray[i] = this->m_StuArray[i + 1];
			}
			this->m_StuNum--; //更新数组中记录成员个数
			//同步更新到文件中
			this->save();

			cout << "删除成功!" << endl;
		}
		else
		{
			cout << "删除失败,未找到该成员" << endl;
		}
	}

	//按任意键清屏
	system("pause");
	system("cls");
}

//判断成员是否存在 如果存在返回成员所在数组中的位置,不存在返回-1
int StudentManager::IsExist(long long id)
{
	int index = -1;

	for (int i = 0; i < this->m_StuNum; i++)
	{
		if (this->m_StuArray[i]->m_Id == id)
		{
			//找到成员
			index = i;

			break;
		}
	}

	return index;
}

//修改成员
void StudentManager::Mod_Stu()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入修改成员学号/工号:" << endl;
		long long id;
		cin >> id;
		int ret = this->IsExist(id);
		if (ret != -1)
		{
			//查找到学号/工号的成员
			delete this->m_StuArray[ret];

			long long newId = 0;
			string newName = "";
			int dSelect = 0;

			cout << "查到:" << id << "号成员,请输入新成员学号/工号:" << endl;
			cin >> newId;

			cout << "请输入新姓名:" << endl;
			cin >> newName;

			cout << "请输入新身份:" << endl;
			cout << "1、学生" << endl;
			cout << "2、老师" << endl;
			cout << "3、院长" << endl;

			cin >> dSelect;

			Member* member = NULL;
			switch (dSelect)
			{
			case 1:
				member = new Student(newId, newName, dSelect);
				break;
			case 2:
				member = new Teacher(newId, newName, dSelect);
				break;
			case 3:
				member = new Dean(newId, newName, dSelect);
				break;
			default:
				break;
			}

			//更新数据到数组中
			this->m_StuArray[ret] = member;

			cout << "修改成功!" << endl;

			//保存到文件中
			this->save();
		}
		else
		{
			cout << "修改失败,查无此人!" << endl;
		}
	}

	//按任意键按清屏
	system("pause");
	system("cls");
}

//查找成员
void StudentManager::Find_Stu()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入查找的方式:" << endl;
		cout << "1、按成员学号/工号查找 " << endl;
		cout << "2、按成员姓名查找 " << endl;

		int select = 0;
		cin >> select;

		if (select == 1)
		{
			//按照编号查
			long long id;
			cout << "请输入查找的成员学号/工号:" << endl;
			cin >> id;

			int ret = IsExist(id);
			if (ret != -1)
			{
				//找到成员
				cout << "查找成功!该成员信息如下:" << endl;
				this->m_StuArray[ret]->showInfo();
			}
			else
			{
				cout << "查找失败,查无此人" << endl;
			}
		}
		else if (select == 2)
		{
			//按照姓名查
			string name;
			cout << "请输入查找的姓名:" << endl;
			cin >> name;

			//加入判断是否查到标志
			bool flag = false; //默认未找到成员
			
			for (int i = 0; i < m_StuNum; i++)
			{
				if (this->m_StuArray[i]->m_Name == name)
				{
					cout << "查找成功,成员学号/工号为:" << this->m_StuArray[i]->m_Id << "号成员信息如下:" << endl;

					flag = true;
					//调用显示信息接口
					this->m_StuArray[i]->showInfo();
				}
			}
			if (flag == false)
			{
				cout << "查找失败,查无此人!" << endl;
			}
		}
		else
		{
			cout << "输入选项有误!" << endl;
		}
	}

	//按任意键清屏
	system("pause");
	system("cls");
}

//按照学号/工号排序
void StudentManager::Sort_Stu()
{
	if (this->m_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 < m_StuNum; i++)
		{
			int minOrMax = i; //声明最小值或最大值下标
			for (int j = i + 1; j < this->m_StuNum; j++)
			{
				if (select == 1) //升序
				{
					if (this->m_StuArray[minOrMax]->m_Id > this->m_StuArray[j]->m_Id)
					{
						minOrMax = j;
					}
				}
				else //降序
				{
					if (this->m_StuArray[minOrMax]->m_Id < this->m_StuArray[j]->m_Id)
					{
						minOrMax = j;
					}
				}
			}

			//判断一开始认定的 最小值或最大值 是不是 计算的最小值或最大值,如果不是 交换数据
			if (i != minOrMax)
			{
				Member* temp = this->m_StuArray[i];
				this->m_StuArray[i] = this->m_StuArray[minOrMax];
				this->m_StuArray[minOrMax] = temp;
			}
		}
		cout << "排序成功!排序后的结果为:" << endl;
		this->save(); //排序后结果保存到文件中,可存可不存,看需求
		this->Show_Stu(); //展示所有成员
	}
}

//清空文件
void StudentManager::Clean_File()
{
	cout << "确定清空?" << endl;
	cout << "1、确定" << endl;
	cout << "2、返回" << endl;

	int select = 0;
	cin >> select;
	if (select == 1)
	{
		//清空文件
		ofstream ofs(FILENAME, ios::trunc); //删除文件后重新创建
		ofs.close();

		if (this->m_StuArray != NULL)
		{
			//删除堆区的每个成员对象
			for (int i = 0; i < this->m_StuNum; i++)
			{
				delete this->m_StuArray[i];
				this->m_StuArray[i] = NULL;
			}

			//删除堆区的数组指针
			delete[] this->m_StuArray;
			this->m_StuArray = NULL;
			this->m_StuNum = 0;
			this->m_FileIsEmpty = true;
		}
		cout << "清空成功!" << endl;
	}

	system("pause");
	system("cls");
}

StudentManager::~StudentManager()
{
	if (this->m_StuArray != NULL)
	{
		for (int i = 0; i < this->m_StuNum; i++)
		{
			if (this->m_StuArray[i] != NULL)
			{
				delete this->m_StuArray[i];
			}
		}
		delete[] this->m_StuArray;
		this->m_StuArray = NULL;
	}
}

15.7 student.cpp

#include"student.h"

//构造函数
Student::Student(long long id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

//显示个人信息
void Student::showInfo()
{
	cout << "成员学号/工号:" << this->m_Id << "\t成员姓名:" << this->m_Name << "\t成员身份:" << this->getDeptName() << "\t成员职责:完成老师留的小游戏作业\n";
}

//获取身份信息
string Student::getDeptName()
{
	return string("学生");
}

15.8 teacher.cpp

#include"teacher.h"

//构造函数
Teacher::Teacher(long long id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

//显示个人信息
void Teacher::showInfo()
{
	cout << "成员学号/工号:" << this->m_Id << "\t成员姓名:" << this->m_Name << "\t成员身份:" << this->getDeptName() << "\t成员职责:完成院长交给的教学任务,并给学生留好结课作业\n";
}

//获取身份名称
string Teacher::getDeptName()
{
	return string("教师");
}

15.9 dean.cpp

#include"dean.h"

//构造函数
Dean::Dean(long long id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

//显示个人信息
void Dean::showInfo()
{
	cout << "成员学号/工号:" << this->m_Id << "\t成员姓名:" << this->m_Name << "\t成员身份:" << this->getDeptName() << "\t成员职责:管理学院所有事务\n";
}

//获取身份名称
string Dean::getDeptName()
{
	return string("院长");
}

15.10 学生管理系统.cpp

#include"studentManager.h"
#include<iostream>
using namespace std;


int main()
{
	//实例化管理者对象
	StudentManager sm;
	
	int choice ; //存储用户

	while (true)
	{
		//调用展示菜单成员函数
		sm.Show_Menu();

		cout << "请输入您的选择: \n";
		cin >> choice;//接受用户选项

		switch (choice)
		{
		case 0: //退出系统
			sm.ExitSystem();
			break;
		case 1: //增加成员
			sm.Add_Stu();
			break;
		case 2: //显示成员
			sm.Show_Stu();
			break;
		case 3: //删除成员
		//{
		//	//测试
		//	int ret = sm.IsExist(202222450410);
		//	if (ret != -1)
		//	{
		//		cout << "成员存在" << endl;
		//	}
		//	else
		//	{
		//		cout << "成员不存在" << endl;
		//	}
		//	break;
		//}
			sm.Del_Stu();
			break;
		case 4: //修改成员
			sm.Mod_Stu();
			break;
		case 5: //查找成员
			sm.Find_Stu();
			break;
		case 6: //排序成员
			sm.Sort_Stu();
			break;
		case 7: //清空文档
			sm.Clean_File();
			break;
		default:
			system("cls"); //清屏
			break;
		}
	}
	//调用展示菜单成员函数
	sm.Show_Menu();

	system("pause");

	return 0;
}

16. 版权声明

本文章为河北经贸大学信息技术学院孙华艺(202222450410)原创文章,未经作者允许不得转载

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HUAYI_SUN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值