C++ 综合大案例 :机房预约系统(2)

本文详细介绍了C++实现的机房预约系统中管理员模块的功能,包括登录注销、子菜单实现、账号添加与显示、机房信息查看和清空预约等功能。通过构造函数初始化管理员信息,实现菜单功能并对接接口,确保账号去重,展示了完整的代码实现和测试过程。
摘要由CSDN通过智能技术生成

C++系列内容的学习目录 → \rightarrow C++学习系列内容汇总

  本案例由于内容较多,故分为四个篇章。
    1-6部分的内容见 C++ 综合大案例 :机房预约系统(1)
    7部分的内容见 C++ 综合大案例 :机房预约系统(2)
    8-9部分的内容见 C++ 综合大案例 :机房预约系统(3)
    10部分的内容见 C++ 综合大案例 :机房预约系统(4)

1. 机房预约系统需求

2. 创建项目

3. 创建主菜单

4. 退出功能实现

5. 创建身份类

6. 登录模块

  1-6部分的内容见C++ 综合大案例 :机房预约系统(1)

7. 管理员模块

7.1 管理员登录和注销

7.1.1 构造函数

  在manager.cpp文件的有参构造函数中,初始化管理员信息,代码如下所示。

//有参构造函数(参数:姓名、密码)
Manager::Manager(string name, string pwd)
{
	//初始化管理员信息
	this->m_Name = name;
	this->m_Pwd = pwd;
}

7.1.2 管理员子菜单

  • 机房预约系统.cpp中,当用户登录的是管理员账号时,添加管理员菜单接口。
  • 将不同的分支提供出来:
       ⋄ \diamond 添加账号
       ⋄ \diamond 查看账号
       ⋄ \diamond 查看机房
       ⋄ \diamond 清空预约
       ⋄ \diamond 注销登录
  • 实现注销功能。

  在机房预约系统.cpp文件中添加全局函数 void managerMenu(Identity * &manager),代码如下所示。

//进入管理员子菜单界面
void managerMenu(Identity * &manager)
{
	while (true)  //只有选择注销登录,才退出循环
	{
		//调用管理员子菜单
		manager->operMenu();

		//将父类指针转为子类指针,调用子类里的其他接口
		Manager * man = (Manager*)manager;

		int select = 0;
		
		cin >> select;  //接收用户选择

		if (select == 1)  //添加账号
		{
			cout << "添加账号" << endl;
			man->addPerson();
		}
		else if (select == 2)  //查看账号
		{
			cout << "查看账号" << endl;
			man->showPerson();
		}
		else if (select == 3)  //查看机房
		{
			cout << "查看机房" << endl;
			man->showComputer();
		}
		else if (select == 4)  //清空预约
		{
			cout << "清空预约" << endl;
			man->cleanFile();
		}
		else  //注销登录
		{
			delete manager;  //销毁掉堆区对象
			cout << "注销成功!" << endl;
			system("pause");
			system("cls");
			return;
		}
	}
}

7.1.3 菜单功能实现

  在manager.cpp中实现成员函数void Manager::operMenu() ,代码如下所示。

//菜单界面
void Manager::operMenu()
{
	cout << "欢迎管理员:" << this->m_Name << "登录!" << endl;
	cout << "\t\t ---------------------------------\n";
	cout << "\t\t|                                |\n";
	cout << "\t\t|          1.添加账号            |\n";
	cout << "\t\t|                                |\n";
	cout << "\t\t|          2.查看账号            |\n";
	cout << "\t\t|                                |\n";
	cout << "\t\t|          3.查看机房            |\n";
	cout << "\t\t|                                |\n";
	cout << "\t\t|          4.清空预约            |\n";
	cout << "\t\t|                                |\n";
	cout << "\t\t|          0.注销登录            |\n";
	cout << "\t\t|                                |\n";
	cout << "\t\t ---------------------------------\n";
	cout << "请选择您的操作: " << endl;
}

7.1.4 接口对接

  在机房预约系统.cpp文件LoginIn()函数的管理员分支中添加如下所示的代码,在管理员成功登录后,调用管理员子菜单界面。

				//进入管理员身份的子菜单
				managerMenu(person);

  管理员成功登录的测试效果如下图所示。

在这里插入图片描述
  管理员成功登录后,调用管理员子菜单界面的测试效果如下图所示。

在这里插入图片描述
  注销登录的测试效果如下图所示。

在这里插入图片描述
  至此,管理员身份可以成功登录以及注销!

7.2 添加账号

  功能描述: 给学生或老师添加新的账号。

  功能要求: 添加时学生的学号不能重复、老师的职工号不能重复。

7.2.1 添加功能实现

  在manager.cpp文件实现addPerson()成员函数,以实现添加新账号功能,代码如下所示。

//添加账号
void Manager::addPerson()
{
	cout << "请输入添加账号的类型:" << endl;
	cout << "1. 添加学生" << endl;
	cout << "2. 添加老师" << endl;

	string fileName;  //操作文件名
	string tip;  //提示id号

	ofstream ofs;  //文件操作对象

	int select = 0;
	cin >> select;

	if (select == 1)
	{
		//添加的是学生
		fileName = STUDENT_FILE;
		tip = "请输入学号:";
	}
	else
	{
		fileName = TEACHER_FILE;
		tip = "请输入职工号:";
	}

	ofs.open(fileName, ios::out | ios::app);  //利用追加的方式写文件

	int id;  //学号或职工号
	string name;  //姓名
	string pwd;  //密码

	cout << tip << endl;
	cin >> id;

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

	cout << "请输入密码:" << endl;
	cin >> pwd;

	//向文件中添加数据
	ofs << id << " " << name << " " << pwd << " " << endl;
	cout << "添加成功!" << endl;

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

	ofs.close();
}

  在测试添加新账号的功能前,先将我们之前测试代码时自己保存的学生和老师账号信息进行清除,然后运行程序进行测试。

  • 测试:添加学生,效果如下图所示。
      
    在这里插入图片描述  
      打开 student.txt 文件,发现成功在文件中添加了一条学生信息。
      
    在这里插入图片描述  
  • 测试:添加老师,效果如下图所示。
      
    在这里插入图片描述  
      打开 teacher.txt 文件,发现成功在文件中添加了一条老师信息。
      
    在这里插入图片描述

7.2.2 去重操作

  功能描述: 添加新账号时,如果是重复的学号,或是重复的职工号,则提示有误。

7.2.2.1 读取信息
  • 要去除重复的账号,首先要先将学生和老师的账号信息获取到程序中,方可检测。
  • manager.h中,添加两个容器,用于存放学生和老师的信息。
  • 添加一个新的成员函数 void initVector() ,初始化容器。

  在manager.h中的管理员类Manager中,添加两个容器和一个新的成员函数,代码如下所示。

	//初始化容器
	void initVector();

	//学生容器
	vector<Student>vStu;

	//老师容器
	vector<Teacher>vTea;

  在manager.cpp中实现成员函数 void initVector(),获取目前的学生和老师信息,代码如下所示。

//初始化容器
void Manager::initVector()
{
	//确保容器清空状态
	vStu.clear();
	vTea.clear();
	//读取信息:学生
	ifstream ifs;
	ifs.open(STUDENT_FILE, ios::in);
	if (!ifs.is_open())
	{
		cout << "文件读取失败!" << endl;
		return;
	}

	Student s;
	while (ifs >> s.m_Id && ifs >> s.m_Name && ifs >> s.m_Pwd)
	{
		vStu.push_back(s);
	}
	cout << "当前学生数量为:" << vStu.size() << endl;
	ifs.close();

	//读取信息:老师
	ifs.open(TEACHER_FILE, ios::in);
	Teacher t;
	while (ifs >> t.m_EmpId && ifs >> t.m_Name && ifs >> t.m_Pwd)
	{
		vTea.push_back(t);
	}
	cout << "当前老师数量为:" << vTea.size() << endl;
	ifs.close();
}

  在manager.cpp中的有参构造函数中,添加调用初始化容器函数的代码,如下所示。

	//初始化容器,获取到所有文件中的学生、老师信息
	this->initVector();

  运行代码可以看到测试代码中获取的当前学生和老师数量,测试效果如下图所示。

在这里插入图片描述

7.2.2.2 去重函数封装

  在manager.h文件中添加成员函数bool checkRepeat(int id, int type);,代码如下所示。

	//检测重复(参数1:检测学号、职工号;参数2:检测类型)
	bool checkRepeat(int id, int type);

  在manager.cpp文件中实现成员函数 bool checkRepeat(int id, int type);,代码如下所示。

//检测重复(参数1:检测学号、职工号;参数2:检测类型)
bool Manager::checkRepeat(int id, int type)
{
	if (type == 1)
	{
		//检测学生
		for (vector<Student>::iterator it = vStu.begin(); it != vStu.end(); it++)
		{
			if (id == it->m_Id)
			{
				return true;
			}
		}
	}
	else
	{
		//检测老师
		for (vector<Teacher>::iterator it = vTea.begin(); it != vTea.end(); it++)
		{
			if (id == it->m_EmpId)
			{
				return true;
			}
		}
	}

	return false;  // 没有重复
}
7.2.2.3 添加去重操作

  在添加学生学号或者老师职工号时,检测是否有重复,修改manager.cpp文件中addPerson()函数的代码为如下所示。

	string errorTip;  //重复错误提示
	
	ofstream ofs;  //文件操作对象

	int select = 0;
	cin >> select;

	if (select == 1)
	{
		//添加的是学生
		fileName = STUDENT_FILE;
		tip = "请输入学号:";
		errorTip = "学号重复,请重新输入:";
	}
	else
	{
		fileName = TEACHER_FILE;
		tip = "请输入职工号:";
		errorTip = "职工号重复,请重新输入:";
	}

	ofs.open(fileName, ios::out | ios::app);  //利用追加的方式写文件

	int id;  //学号或职工号
	string name;  //姓名
	string pwd;  //密码

	cout << tip << endl;

	while (true)
	{
		cin >> id;
		bool ret = checkRepeat(id, select);
		if (ret)
		{
			cout << errorTip << endl;
		}
		else
		{
			break;
		}
	}

  测试效果如下图所示。

  • 测试:学生学号有重复
      
    在这里插入图片描述  
  • 测试:老师职工号有重复
      
    在这里插入图片描述
7.2.2.4 bug解决

  bug描述: 虽然可以检测重复的账号,但是刚添加的账号由于没有更新到容器中,因此不会做检测,导致刚加入的账号的学生号或者职工号,再次添加时依然可以重复添加。

  先添加一个学号为3的学生信息。

在这里插入图片描述
  接着再添加一个学号为3的学生信息,不会显示重复,依旧可以添加成功。

在这里插入图片描述
  打开student.txt文件,发现有两个重复的学号为3的学生信息。

在这里插入图片描述
  解决方案: 在每次添加新账号时,重新初始化容器。

  在manager.cpp文件中的addPerson()成员函数的最后添加如下所示的代码。

	//调用初始化容器的接口,重新获取文件中的数据
	this->initVector();

  将student.txt文件中的数据手动清空,再次测试,刚加入的账号不会重复添加了,效果如下图所示。

  先添加一个学号为1的学生信息。

在这里插入图片描述
  接着再添加一个学号为1的学生信息,会显示重复,需要重新输入。

在这里插入图片描述

7.3 显示账号

  功能描述: 显示学生信息或老师信息。

7.3.1 显示功能实现

  在manager.cpp文件实现showPerson()成员函数,以实现显示账号功能,代码如下所示。

void printStudent(Student &s)
{
	cout << "学号:" << s.m_Id << "    姓名:" << s.m_Name << "    密码:" << s.m_Pwd << endl;
}

void printTeacher(Teacher &t)
{
	cout << "职工号:" << t.m_EmpId << "    姓名:" << t.m_Name << "    密码:" << t.m_Pwd << endl;
}

//查看账号
void Manager::showPerson()
{
	cout << "请选择查看的内容:" << endl;
	cout << "1. 查看所有学生" << endl;
	cout << "2. 查看所有老师" << endl;

	int select = 0;  //接受用户选择
	cin >> select;

	if (select == 1)
	{
		//查看学生
		cout << "所有学生的信息如下:" << endl;
		for_each(vStu.begin(), vStu.end(), printStudent);
	}
	else
	{
		//查看老师
		cout << "所有老师的信息如下:" << endl;
		for_each(vTea.begin(), vTea.end(), printTeacher);
	}
	system("pause");
	system("cls");
}

7.3.2 测试

  测试效果如下图所示。

  • 测试:查看学生的信息
      
    在这里插入图片描述  
  • 测试:查看老师的信息
      
    在这里插入图片描述

  至此,显示账号功能实现完毕!

7.4 查看机房

7.4.1 添加机房信息

  案例需求中,机房一共有三个,其中1号机房容量20台机器,2号50台,3号100台,我们可以将信息录入到computerRoom.txt中,如下图所示。

在这里插入图片描述

7.4.2 机房类创建

  在头文件下,创建新的文件computerRoom.h,并添加如下所示的代码。

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

//机房类
class ComputerRoom
{
public:
	int m_ComId;  //机房Id号
	int m_MaxNum;  //机房最大容量
};

7.4.3 初始化机房信息

  在manager.h中的管理员类Manager中,添加机房的容器,用于保存机房信息,代码如下所示。

	//机房信息
	vector<ComputerRoom>vCom;

  在manager.cpp中的有参构造函数中,追加如下所示的代码,初始化机房信息。

	//初始化机房信息
	ifstream ifs;
	ifs.open(COMPUTER_FILE, ios::in);

	ComputerRoom com;
	while (ifs >> com.m_ComId && ifs >> com.m_MaxNum)
	{
		vCom.push_back(com);
	}
	ifs.close();
	cout << "机房的数量为:" << vCom.size() << endl;

  因为机房信息目前版本不会有所改动,如果后期有修改功能,最好封装到一个函数中,方便维护。

7.4.4 显示机房信息

  在manager.cpp中的showComputer()成员函数中,添加如下所示的代码。

//查看机房信息
void Manager::showComputer()
{
	cout << "机房的信息如下:" << endl;
	for (vector<ComputerRoom>::iterator it = vCom.begin(); it != vCom.end(); it++)
	{
		cout << "机房编号:" << it->m_ComId << "    机房最大容量:" << it->m_MaxNum << endl;
	}
	system("pause");
	system("cls");
}

  测试显示机房信息的功能,效果如下图所示。

在这里插入图片描述

7.5 清空预约

  功能描述: 清空生成的order.txt预约文件。

7.5.1 清空功能实现

  在manager.cpp中的cleanFile()成员函数中,添加如下所示的代码。

//清空预约记录
void Manager::cleanFile()
{
	ofstream ofs(ORDER_FILE, ios::trunc);
	ofs.close();

	cout << "清空成功!" << endl;

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

  测试清空,可以随意写入一些信息在order.txt中,然后调用cleanFile()清空文件的接口,查看是否清空干净。

  在order.txt文件中,随意输入一些预约信息,如下图所示。

在这里插入图片描述
  测试预约清空的功能,效果如下图所示。

在这里插入图片描述
  再次打开order.txt文件,发现内容已全部清空。

在这里插入图片描述

8. 学生模块

9. 老师模块

  8-9部分的内容见C++ 综合大案例 :机房预约系统(3)

10. 附录:完整代码

  10部分的内容见C++ 综合大案例 :机房预约系统(4)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值