STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

本文主要是介绍STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂

一、需求分析

高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生
管理员:给学生和实验室教师创建账号并分发
实验室教师:审核学生的预约申请
学生:申请使用实验室

高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验室(可容纳30人)等,管理员可以添加实验室

学生可以预约未来一周内的实验室,需要选择周一至周五的上午、下午或晚上时间段
实验室教师对学生的预约申请进行审核,审核分为通过或不通过
管理员负责每周对学生申请的实验室预约清单进行清空

二、功能详情

1,主页面登录系统选择:学生、实验室教师、管理员、退出

2,学生:输入学号、姓名和登录密码
实验室教师:输入职工号、姓名和登录密码
管理员:输入姓名和登录密码

3,学生功能
申请预约:预约实验室
查看自身的预约:查看自身申请的预约状态
查看所有预约:取消自身的预约,预约成功或审核中的预约都可以随时取消
退出登录

4,实验室教师功能
查看所有学生预约情况:查看全部的实验室预约信息及预约状态
审核学生的预约:对学生申请的实验室预约进行审核
退出登录

5,管理员功能
创建账号:为学生或实验室教师创建账号,需要检测学生学号和教师职工号是否重复
查看账号:查看学生或实验室教师的全部信息
添加实验室:添加实验室的信息,包括实验室的id、名称和最大容量
查看实验室:查看所有实验室的信息
清空预约:清空所有的预约记录
退出登录

三、项目创建

1,新建C++空项目

在这里插入图片描述

2,创建主菜单及退出功能的实现

创建项目入口,即主页面main.cpp
在这里插入图片描述
通过switch case分支进行不同身份的登录,
退出功能没啥好说的,用户选择0之后直接return 0;即可

#include <iostream>int main() {int select = 0;//存放用户的选择while (true){std::cout << "======================  Welcome to the Laboratory Management System  =====================" << std::endl;std::cout << "\t\t -------------------------------\n";std::cout << "\t\t|          1.Student            |\n";std::cout << "\t\t|          2.Teacher            |\n";std::cout << "\t\t|          3.Admin              |\n";std::cout << "\t\t|          0.Exit               |\n";std::cout << "\t\t -------------------------------\n";std::cout << std::endl << "Please enter your identity: " << std::endl;std::cin >> select; //接受用户选择switch (select){case 1:  //学生身份break;case 2:  //老师身份break;case 3:  //管理员身份break;case 0:  //退出系统std::cout << "Welcome to you next time!" << std::endl;system("pause");return 0;break;default:std::cout << "You have entered the wrong information, please make a new selection!" << std::endl;system("pause");system("cls");break;}}system("pause");return 0;
}

3,身份类创建——搭建框架

无论Student、Teacher还是Admin,都有相通的共性(姓名和密码),抽取出来整合成一个基类
继承这个基类,不同的子类根据自身的特性再新增属性功能即可

①身份类基类——Identify

经过功能详情的分析,三种不同身份的共性是:name和pwd
因为不同身份登录成功需要进入到不同的页面,再基类中通过纯虚函数定义一个接口,子类根据自身情况实现即可
基类只需要声明,不需要实现

身份类基类:Identify.h

#pragma once
#include <iostream>
class Identify 
{
public:virtual void selectMenu() = 0;//纯虚函数,不同用户登录成功之后显示的菜单均不同std::string getName() {return this->name_;}std::string getPwd(){return this->pwd_;}void setName(std::string name){this->name_ = name;}void setPwd(std::string pwd){this->pwd_ = pwd;}private:std::string name_;//姓名std::string pwd_;//密码
};

②Student类

在这里插入图片描述

学生具有的功能:申请预约、显示我的预约、查看所有预约和取消预约

Student.h

#pragma once
#include "Identify.h"
class Student:public Identify
{
public:Student();Student(int id,std::string name,std::string pwd);//学号、姓名、密码virtual void Identify::selectMenu() override;//重写基类中的虚函数void applyOrder();//申请预约功能void showMyOrder();//显示我的预约功能void showAllOrder();//查看所有预约功能void cancelOrder();//取消预约功能int getId() {return this->student_id_;}void setId(int id) {this->student_id_ = id;}private:int student_id_;
};

Student.cpp

#include "Student.h"
Student::Student() {}
Student::Student(int id,std::string name,std::string pwd) {}void Student::selectMenu() {}//功能菜单实现void Student::applyOrder() {}//预约申请实现
void Student::showMyOrder() {}//显示我的预约
void Student::showAllOrder() {}//显示所有预约
void Student::cancelOrder() {}//取消预约

③Teacher类

在这里插入图片描述

教师具有的功能:显示所有预约和审核预约

Teacher.h

#pragma once
#include "Identify.h"
class Teacher:public Identify
{
public:Teacher();Teacher(int teacher_id,std::string name,std::string pwd);virtual void Identify::selectMenu() override;//功能菜单实现void showAllOrder();//显示所有预约void validOrder();//审核预约int getId() {return this->teaher_id_;}void setId(int id) {this->teaher_id_ = id;}private:int teaher_id_;//教职工编号
};

Teacher.cpp

#include "Teacher.h"
Teacher::Teacher() {}
Teacher::Teacher(int teacher_id,std::string name,std::string pwd) {}void Teacher::selectMenu() {}//功能菜单实现void Teacher::showAllOrder() {}//显示所有预约
void Teacher::validOrder() {}//审核预约

④Admin类

在这里插入图片描述

管理员具有的功能:添加用户(包括学生和教职工)、查看用户、看实验室信息和清空预约记录

Admin.h

#pragma once
#include <iostream>
#include "Identify.h"
class Admin:public Identify
{
public:Admin();Admin(std::string name,std::string pwd);virtual void Identify::selectMenu() override;//功能菜单实现void addUser();//添加用户void showUser();//查看用户void showLabInfo();//查看实验室信息void cleanRecord();//清空预约记录
};

Admin.cpp

#include "Admin.h"
Admin::Admin() {}
Admin::Admin(std::string name, std::string pwd) {}void Admin::selectMenu(){}//功能菜单实现void Admin::addUser() {}//添加用户功能实现
void Admin::showUser() {}//查看用户功能实现
void Admin::showLabInfo() {}//查看实验室信息功能实现
void Admin::cleanRecord() {}//清空预约记录功能实现

4,登录模块

①全局文件

在这里插入图片描述
将不同身份的账号密码等信息存放到文件中,将所有的文件名都定义到全局文件中
通过宏定义进行关联文件,方便后续的操作

globalFile.h

#pragma once //管理员文件
#define ADMIN_FILE     "admin.txt"
//学生文件
#define STUDENT_FILE   "student.txt"
//教师文件
#define TEACHER_FILE   "teacher.txt"
//实验室信息文件
#define LABORATORY_FILE  "laboratoryRoom.txt"
//订单文件
#define ORDER_FILE     "order.txt"

同级路径下创建对应的txt文本文件
在这里插入图片描述

②登录函数封装

main.cpp中添加一个全局函数Login,根据用户的选择进行不同的身份登录操作
void Login(string fileName, int type)
参数一:操作的文件名称
参数二:身份(1为学生、2为实验室教师、3为管理员)

main.cpp

#include <iostream>
#include "Identify.h"
#include <fstream>
#include "globalFile.h"
#include "Student.h"
#include "Teacher.h"
#include "Admin.h"//全局登录函数
//参数一:操作的文件名称
//参数二:身份(1为学生、2为实验室教师、3为管理员)
void Login(std::string fileName,int type) 
{//创建父类指针,将来通过多态指向子类对象Identify* identify_p= NULL;//读取文件std::ifstream ifs;ifs.open(fileName, std::ios::in);//以读的方式打开文件//若文件不存在if (!ifs.is_open()) //打开失败{std::cout << "The file does not exist" << std::endl;ifs.close();return;}//存放用户将来输入的信息int id = 0;//存储学号或职工号std::string name;//学生或实验室教师的姓名std::string pwd;//学生或实验室教师的密码if (type == 1) {std::cout << "Please input your student_id:" << std::endl;std::cin >> id;}else if (type == 2) {std::cout << "Please input your teacher_id:" << std::endl;std::cin >> id;}std::cout << "Please input your name:" << std::endl;std::cin >> name;std::cout << "Please input your password:" << std::endl;std::cin >> pwd;if (type == 1){//student login//todo}else if (type == 2) {//teacher login//todo}else if (type == 3) {//admin login//todo}std::cout << "Validation failed !" << std::endl;system("pause");system("cls");return;
}int main() {int select = 0;//存放用户的选择while (true){std::cout << "======================  Welcome to the Laboratory Management System  =====================" << std::endl;std::cout << "\t\t -------------------------------\n";std::cout << "\t\t|          1.Student            |\n";std::cout << "\t\t|          2.Teacher            |\n";std::cout << "\t\t|          3.Admin              |\n";std::cout << "\t\t|          0.Exit               |\n";std::cout << "\t\t -------------------------------\n";std::cout << std::endl << "Please enter your identity: " << std::endl;std::cin >> select; //接受用户选择switch (select){case 1:  //学生身份Login(STUDENT_FILE,1);break;case 2:  //老师身份Login(TEACHER_FILE, 2);break;case 3:  //管理员身份Login(ADMIN_FILE, 3);break;case 0:  //退出系统std::cout << "Welcome to you next time!" << std::endl;system("pause");return 0;break;default:std::cout << "You have entered the wrong information, please make a new selection!" << std::endl;system("pause");system("cls");break;}}system("pause");return 0;
}

③学生登录实现

student.txt中添加几条记录信息进行测试
在这里插入图片描述

修改完善主函数main中的全局登录函数Login
main.cpp

//全局登录函数
//参数一:操作的文件名称
//参数二:身份(1为学生、2为实验室教师、3为管理员)
void Login(std::string fileName,int type) 
{//创建父类指针,将来通过多态指向子类对象Identify* identify_p = NULL;//读取文件std::ifstream ifs;ifs.open(fileName, std::ios::in);//以读的方式打开文件//若文件不存在if (!ifs.is_open()) //打开失败{std::cout << "The file does not exist" << std::endl;ifs.close();return;}//存放用户将来输入的信息int id = 0;//存储学号或职工号std::string name;//学生或实验室教师的姓名std::string pwd;//学生或实验室教师的密码if (type == 1) {std::cout << "Please input your student_id:" << std::endl;std::cin >> id;}else if (type == 2) {std::cout << "Please input your teacher_id:" << std::endl;std::cin >> id;}std::cout << "Please input your name:" << std::endl;std::cin >> name;std::cout << "Please input your password:" << std::endl;std::cin >> pwd;if (type == 1){//student loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd) //学号、姓名、密码均输入成功{std::cout << "Student verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Student(id, name, pwd);//父类指针指向子类对象,创建学生实例//进入学生身份的子菜单 todoreturn;}}}else if (type == 2) {//teacher login}else if (type == 3) {//admin login}std::cout << "Validation failed !" << std::endl;system("pause");system("cls");return;
}

测试效果:
在这里插入图片描述
在这里插入图片描述

④实验室教师登录实现

teacher.txt中添加几条记录信息进行测试
在这里插入图片描述

修改完善main.cpp中的全局登录函数Login
main.cpp

//全局登录函数
//参数一:操作的文件名称
//参数二:身份(1为学生、2为实验室教师、3为管理员)
void Login(std::string fileName,int type) 
{//创建父类指针,将来通过多态指向子类对象Identify* identify_p = NULL;//读取文件std::ifstream ifs;ifs.open(fileName, std::ios::in);//以读的方式打开文件//若文件不存在if (!ifs.is_open()) //打开失败{std::cout << "The file does not exist" << std::endl;ifs.close();return;}//存放用户将来输入的信息int id = 0;//存储学号或职工号std::string name;//学生或实验室教师的姓名std::string pwd;//学生或实验室教师的密码if (type == 1) {std::cout << "Please input your student_id:" << std::endl;std::cin >> id;}else if (type == 2) {std::cout << "Please input your teacher_id:" << std::endl;std::cin >> id;}std::cout << "Please input your name:" << std::endl;std::cin >> name;std::cout << "Please input your password:" << std::endl;std::cin >> pwd;if (type == 1){//student loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd) //学号、姓名、密码均输入成功{std::cout << "Student verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Student(id, name, pwd);//父类指针指向子类对象,创建学生实例//进入学生身份的子菜单 todoreturn;}}}else if (type == 2) {//teacher loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd)//教职工编号、姓名、密码输入成功 {std::cout << "Teacher verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Teacher(id, name, pwd);//父类指针指向子类对象,创建教职工实例//进入实验室教师身份的子菜单 todoreturn;}}}else if (type == 3) {//admin login}std::cout << "Validation failed !" << std::endl;system("pause");system("cls");return;
}

测试效果:
在这里插入图片描述
在这里插入图片描述

⑤管理员登录实现

admin.txt中添加几条记录信息进行测试
在这里插入图片描述

修改完善main.cpp中的全局登录函数Login
main.cpp

//全局登录函数
//参数一:操作的文件名称
//参数二:身份(1为学生、2为实验室教师、3为管理员)
void Login(std::string fileName,int type) 
{//创建父类指针,将来通过多态指向子类对象Identify* identify_p = NULL;//读取文件std::ifstream ifs;ifs.open(fileName, std::ios::in);//以读的方式打开文件//若文件不存在if (!ifs.is_open()) //打开失败{std::cout << "The file does not exist" << std::endl;ifs.close();return;}//存放用户将来输入的信息int id = 0;//存储学号或职工号std::string name;//学生或实验室教师的姓名std::string pwd;//学生或实验室教师的密码if (type == 1) {std::cout << "Please input your student_id:" << std::endl;std::cin >> id;}else if (type == 2) {std::cout << "Please input your teacher_id:" << std::endl;std::cin >> id;}std::cout << "Please input your name:" << std::endl;std::cin >> name;std::cout << "Please input your password:" << std::endl;std::cin >> pwd;if (type == 1){//student loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd) //学号、姓名、密码均输入成功{std::cout << "Student verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Student(id, name, pwd);//父类指针指向子类对象,创建学生实例//进入学生身份的子菜单 todoreturn;}}}else if (type == 2) {//teacher loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd)//教职工编号、姓名、密码输入成功 {std::cout << "Teacher verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Teacher(id, name, pwd);//父类指针指向子类对象,创建教职工实例//进入实验室教师身份的子菜单 todoreturn;}}}else if (type == 3) {//admin loginstd::string f_name;//从文件中获取得到的namestd::string f_pwd;//从文件中获取得到的pwdwhile (ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_name == name && f_pwd == pwd) //管理员登录只需要姓名和密码 {std::cout << "Admin verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Admin(name, pwd);//父类指针指向子类对象,创建管理员实例//进入管理员身份的子菜单 todoreturn;}}}std::cout << "Validation failed !" << std::endl;system("pause");system("cls");return;
}

测试效果:
在这里插入图片描述
在这里插入图片描述

5,管理员模块

实验室教师和学生的账号信息是由管理员进行创建的,故首先得搞定管理员
管理员功能:登录和注销
首先,有参构造记录一下管理员信息、
其次,进入到管理员身份对应的子菜单页面中,管理员的功能包括添加账号、查看账号、查看实验室、清空预约、注销登录
最后,在main.cpp中添加全局函数adminMenu()进行显示管理员菜单,根据用户选择的功能进行对应的函数实现

①登录和注销功能——AdminMenu()

Admin.h头文件定义的函数不需要改变
Admin.cpp实现头文件中所定义的一些函数,函数selectMenu()显示功能菜单的实现

Admin.cpp

#include "Admin.h"
Admin::Admin() {}Admin::Admin(std::string name, std::string pwd) 
{//初始化管理员信息Admin::setName(name);Admin::setPwd(pwd);
}void Admin::selectMenu()//功能菜单实现
{std::cout << "Welcome admin: " << this->getName() << " login!" << std::endl;std::cout << "\t\t --------------------------------\n";std::cout << "\t\t|          1.addUser             |\n";std::cout << "\t\t|          2.showUser            |\n";std::cout << "\t\t|          3.addLabInfo          |\n";std::cout << "\t\t|          4.showLabInfo         |\n";std::cout << "\t\t|          5.cleanRecord         |\n";std::cout << "\t\t|          0 or OtherKey.logout  |\n";std::cout << "\t\t --------------------------------\n";std::cout << "Please select your action: " << std::endl;
}void Admin::addUser() {}//添加用户功能实现
void Admin::showUser() {}//查看用户功能实现
void Admin::showLabInfo() {}//查看实验室信息功能实现
void Admin::cleanRecord() {}//清空预约记录功能实现

定义全局函数AdminMenu()用于显示管理员身份菜单界面
Login()登录全局函数中进行调用即可
在这里插入图片描述

main.cpp

//管理员身份菜单界面
void AdminMenu(Identify*& identify_p) //传入父类的指针
{//进入菜单界面while (true) {//调用管理员子菜单identify_p->selectMenu();//这是父类指针,只能调用公共的接口纯虚函数//想要调用子类特有的接口,需要把父类指针转回去,将父类的指针转为子类的指针Admin* admin = (Admin*)identify_p;int userselect = 0;//用户的选择std::cin >> userselect;//接收用户的选择if (userselect == 1) //添加账号{std::cout << "Your select is add an account" << std::endl;admin->addUser();}else if (userselect == 2)//查看账号{std::cout << "Your select is view all account" << std::endl;admin->showUser();}else if (userselect == 3) //添加实验室信息{std::cout << "Your select is add lab information" << std::endl;admin->addLabInfo();}else if (userselect == 4) //显示实验室信息{std::cout << "Your select is show lab information" << std::endl;admin->showLabInfo();}else if (userselect == 5) //清空预约{std::cout << "Your select is clear all appointment" << std::endl;admin->cleanRecord();}else//选成其他选项,默认代表注销登录{delete admin;//销毁堆区创建的对象std::cout << "The logout is successful" << std::endl;system("pause");system("cls");return;}}
}//全局登录函数
//参数一:操作的文件名称
//参数二:身份(1为学生、2为实验室教师、3为管理员)
void Login(std::string fileName,int type) 
{//创建父类指针,将来通过多态指向子类对象Identify* identify_p = NULL;//读取文件std::ifstream ifs;ifs.open(fileName, std::ios::in);//以读的方式打开文件//若文件不存在if (!ifs.is_open()) //打开失败{std::cout << "The file does not exist" << std::endl;ifs.close();return;}//存放用户将来输入的信息int id = 0;//存储学号或职工号std::string name;//学生或实验室教师的姓名std::string pwd;//学生或实验室教师的密码if (type == 1) {std::cout << "Please input your student_id:" << std::endl;std::cin >> id;}else if (type == 2) {std::cout << "Please input your teacher_id:" << std::endl;std::cin >> id;}std::cout << "Please input your name:" << std::endl;std::cin >> name;std::cout << "Please input your password:" << std::endl;std::cin >> pwd;if (type == 1){//student loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd) //学号、姓名、密码均输入成功{std::cout << "Student verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Student(id, name, pwd);//父类指针指向子类对象,创建学生实例//进入学生身份的子菜单 todoreturn;}}}else if (type == 2) {//teacher loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd)//教职工编号、姓名、密码输入成功 {std::cout << "Teacher verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Teacher(id, name, pwd);//父类指针指向子类对象,创建教职工实例//进入实验室教师身份的子菜单 todoreturn;}}}else if (type == 3) {//admin loginstd::string f_name;//从文件中获取得到的namestd::string f_pwd;//从文件中获取得到的pwdwhile (ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_name == name && f_pwd == pwd) //管理员登录只需要姓名和密码 {std::cout << "Admin verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Admin(name, pwd);//父类指针指向子类对象,创建管理员实例//进入管理员身份的子菜单AdminMenu(identify_p);return;}}}std::cout << "Validation failed !" << std::endl;system("pause");system("cls");return;
}

测试效果:
在这里插入图片描述

②添加用户功能——addUser()

为学生和实验室教师添加账号,要求添加账号的时候学号和职工号不能够重复
对接口addUser()进行实现

Admin.cpp

void Admin::addUser()添加用户功能实现 
{std::string fileType;//根据用户的选择进行操作不同的文件std::string tip;//提示是学号还是职工号std::string repeat_tip;//重复提示信息std::ofstream ofs;//文件操作对象int userselect = 0;//获取用户的选择while (true){//提示用户std::cout << "Please enter the type of account you want to add (1.student or 2.teacher):" << std::endl;std::cout << "1、student" << std::endl;std::cout << "2、teacher" << std::endl;std::cout << "0、exit" << std::endl;std::cin >> userselect;if (userselect == 1)//添加学生{fileType = STUDENT_FILE;tip = "please input studentID: ";repeat_tip = "studentID already exists, please input again: ";break;}else if (userselect == 2)//添加老师{fileType = TEACHER_FILE;tip = "please input teacherID: ";repeat_tip = "teacherID already exists, please input again: ";break;}else if(userselect == 0){system("cls");//清屏return;}else {std::cout << "Invalid input, please try again." << std::endl;}}ofs.open(fileType, std::ios::app);//以追加的方式写入文件if (!ofs.is_open())//文件打开失败{std::cout << "Failed to open file: " << fileType << std::endl;return;}int id;//学号或职工号std::string name;//姓名std::string pwd;//密码std::cout << tip << std::endl;//提示输入学号或职工号while (true) {std::cin >> id;bool repeat = this->checkRepeate(id, userselect);//检查是否有重复的用户if (repeat)//有重复的用户{std::cout << repeat_tip << std::endl;}else//没有重复的用户{break;}}std::cout << "please input name: " << std::endl;std::cin >> name;//输入姓名std::cout << "please input password: " << std::endl;std::cin >> pwd;//输入密码//写入文件ofs << id << " " << name << " " << pwd << " " << std::endl;ofs.close();std::cout << "Add user successfully!" << std::endl;system("pause");//暂停程序system("cls");//清屏
}

测试效果:
在这里插入图片描述
在这里插入图片描述
运行完之后,teacher信息里面多了个账号
在这里插入图片描述
同样,student信息里面也会多一个账号
在这里插入图片描述

去重操作

添加新账号的时候,要避免学号\职工号的重复

解决思路:
首先,在Admin.h中,把学生和实验室教师账号文件信息全部读到各自的容器中,两个容器(std::vector v_Studentvector v_Teacher)分别存放实验室教师和学生所有账号信息
然后,在Admin.h中,添加一个成员函数void init_Stu_Tea_Vector()用于对学生和实验室教师信息的容器(v_Studentv_Teacher)进行初始化也就是将对应的文本文件数据对应读取到这两个容器中
再次,在Admin.cpp中,对成员函数void init_Stu_Tea_Vector()进行实现,并在构造函数中对两个容器初始化(this->initVector())
其次,在Admin.h中,添加成员函数bool checkRepeat(int id, int type); id表示职工号\学号、type表示类型,1为学生,2为实验室教师用于检查两个容器(v_Studentv_Teacher)中是否已存在管理员当前注册时输入的学号\职工号(id)信息,存在为true,不存在为false
最后,每次添加完新用户之后,需要重新初始化容器(即将新的账号文件全部重新读取到容器中),并在每次调用添加用户的函数(void Admin::addUser)的最后进行初始化(this->init_Stu_Tea_Vector())即可

Admin.h

	void init_Stu_Tea_Vector();//初始化容器,用于将对应的文本文件信息读取到对应的容器中std::vector<Student> v_Student;//学生容器std::vector<Teacher> v_Teacher;//教师容器bool checkRepeate(int id, int type);//检查学号\职工号是否重复

Admin.cpp

#include "Admin.h"
Admin::Admin() {}Admin::Admin(std::string name, std::string pwd) 
{//初始化管理员信息Admin::setName(name);Admin::setPwd(pwd);//初始化学生和老师的容器,获取文件中所有老师和学生的信息this->init_Stu_Tea_Vector();
}void Admin::selectMenu()//功能菜单实现
{std::cout << "Welcome admin: " << this->getName() << " login!" << std::endl;std::cout << "\t\t --------------------------------\n";std::cout << "\t\t|          1.addUser             |\n";std::cout << "\t\t|          2.showUser            |\n";std::cout << "\t\t|          3.showLabInfo         |\n";std::cout << "\t\t|          4.cleanRecord         |\n";std::cout << "\t\t|          0.logout              |\n";std::cout << "\t\t --------------------------------\n";std::cout << "Please select your action: " << std::endl;
}void Admin::addUser()添加用户功能实现 
{std::string fileType;//根据用户的选择进行操作不同的文件std::string tip;//提示是学号还是职工号std::string repeat_tip;//重复提示信息std::ofstream ofs;//文件操作对象int userselect = 0;//获取用户的选择while (true){//提示用户std::cout << "Please enter the type of account you want to add (1.student or 2.teacher):" << std::endl;std::cout << "1、student" << std::endl;std::cout << "2、teacher" << std::endl;std::cout << "0、exit" << std::endl;std::cin >> userselect;if (userselect == 1)//添加学生{fileType = STUDENT_FILE;tip = "please input studentID: ";repeat_tip = "studentID already exists, please input again: ";break;}else if (userselect == 2)//添加老师{fileType = TEACHER_FILE;tip = "please input teacherID: ";repeat_tip = "teacherID already exists, please input again: ";break;}else if(userselect == 0){system("cls");//清屏return;}else {std::cout << "Invalid input, please try again." << std::endl;}}ofs.open(fileType, std::ios::app);//以追加的方式写入文件if (!ofs.is_open())//文件打开失败{std::cout << "Failed to open file: " << fileType << std::endl;return;}int id;//学号或职工号std::string name;//姓名std::string pwd;//密码std::cout << tip << std::endl;//提示输入学号或职工号while (true) {std::cin >> id;bool repeat = this->checkRepeate(id, userselect);//检查是否有重复的用户if (repeat)//有重复的用户{std::cout << repeat_tip << std::endl;}else//没有重复的用户{break;}}std::cout << "please input name: " << std::endl;std::cin >> name;//输入姓名std::cout << "please input password: " << std::endl;std::cin >> pwd;//输入密码//写入文件ofs << id << " " << name << " " << pwd << " " << std::endl;ofs.close();std::cout << "Add user successfully!" << std::endl;system("pause");//暂停程序system("cls");//清屏this->init_Stu_Tea_Vector();//刷新容器,重新读取文件中的用户信息
}void Admin::init_Stu_Tea_Vector()//初始化学生和老师的容器,用于存放从文件中读取的所有用户信息
{//对容器进行初始化,清空用于存放对应用户信息的容器this->v_Student.clear();this->v_Teacher.clear();std::ifstream ifs;//文件读取操作对象//读取学生信息ifs.open(STUDENT_FILE, std::ios::in);//以读取的方式打开学生文件if (!ifs.is_open())//文件打开失败{std::cout << "Failed to open file: " << STUDENT_FILE << std::endl;return;}Student student;int student_id;std::string student_name;std::string student_pwd;while (ifs >> student_id && ifs >> student_name && ifs >> student_pwd){student.setId(student_id);student.setName(student_name);student.setPwd(student_pwd);v_Student.push_back(student);}std::cout << "Read student information successfully!" << std::endl;std::cout<<"Student size: "<<v_Student.size()<<std::endl;ifs.close();//读取老师信息ifs.open(TEACHER_FILE, std::ios::in);//以读取的方式打开老师文件if (!ifs.is_open())//文件打开失败{std::cout << "Failed to open file: " << TEACHER_FILE << std::endl;return;}Teacher teacher;int teacher_id;std::string teacher_name;std::string teacher_pwd;while (ifs >> teacher_id && ifs >> teacher_name && ifs >> teacher_pwd){teacher.setId(teacher_id);teacher.setName(teacher_name);teacher.setPwd(teacher_pwd);v_Teacher.push_back(teacher);}std::cout << "Read teacher information successfully!" << std::endl;std::cout << "Teacher size: " << v_Teacher.size() << std::endl;ifs.close();
}bool Admin::checkRepeate(int id,int fileType)//检查是否有重复的用户
{if (fileType == 1)//学生{for (int i = 0; i < v_Student.size(); i++){if (v_Student[i].getId() == id){return true;}}}else if (fileType == 2)//老师{for (int i = 0; i < v_Teacher.size(); i++){if (v_Teacher[i].getId() == id){return true;}}}return false;
}void Admin::showUser() {}//查看用户功能实现
void Admin::showLabInfo() {}//查看实验室信息功能实现
void Admin::cleanRecord() {}//清空预约记录功能实现

③显示账号功能——showUser()

显示账号功能函数(showUser())的实现

接收用户的选择,根据用户的不同选择进行遍历添加用户功能中所定义的分别存放实验室教师和学生所有账号信息的两个容器(std::vector v_Studentvector v_Teacher),输出即可

admin.cpp

void Admin::showUser() //查看用户功能实现
{while (true){std::cout << "Please enter the type of account you want to show (1.student or 2.teacher):" << std::endl;std::cout << "1、student" << std::endl;std::cout << "2、teacher" << std::endl;std::cout << "0、exit" << std::endl;int userselect = 0;std::cin >> userselect;if (userselect == 1)//查看所有学生的信息{std::cout << "Student information:" << std::endl;std::for_each(v_Student.begin(), v_Student.end(), printStudent);system("pause");//暂停程序system("cls");//清屏break;}else if (userselect == 2)//查看所有老师的信息{std::cout << "Teacher information:" << std::endl;std::for_each(v_Teacher.begin(), v_Teacher.end(), printTeacher);system("pause");//暂停程序system("cls");//清屏break;}else if (userselect == 0)//退出{system("cls");//清屏break;}else{std::cout << "Invalid input, please try again." << std::endl;system("pause");//暂停程序system("cls");//清屏}}
}

④添加实验室信息功能——addLabInfo()

首先,在Admin.h中,把实验室信息全部读到容器(std::vector v_Lab)中
然后,在Admin.h中,添加一个成员函数void init_Lab_Vector()用于对实验室信息的容器(std::vector v_Lab)进行初始化,也就是将实验室文本文件数据对应读取到这个容器中
再次,在Admin.cpp中,对成员函数void init_Lab_Vector()进行实现,并在构造函数中对两个容器初始化(this->init_Lab_Vector())
其次,在Admin.h中,添加成员函数bool checkRepeat(int id, int type); id表示职工号\学号\实验室编号、type表示类型,1为学生,2为实验室教师,3为实验室用于检查容器(std::vector v_Lab)中是否已存在管理员当前注册时输入的实验室编号信息,存在为true,不存在为false
最后,每次添加完新实验室之后,需要重新初始化容器(即将新的实验室信息文件全部重新读取到容器中),并在每次调用添加实验室的函数(void Admin::addLabInfo)的最后进行初始化(this->init_Lab_Vector())即可

创建一个实验室类
Laboratory.h

#pragma once
#include <iostream>//实验室类
class Laboratory
{
public:Laboratory() {};Laboratory(int id, std::string name, int capacity):lab_id_(id), lab_name_(name), lab_max_capacity_(capacity) {}void set_lab_id(int id) { this->lab_id_ = id; }void set_lab_name(std::string name) { this->lab_name_ = name; }void set_lab_max_capacity(int capacity) { this->lab_max_capacity_ = capacity; }int get_lab_id() const { return this->lab_id_; }std::string get_lab_name() const { return this->lab_name_; }int get_lab_max_capacity() const { return this->lab_max_capacity_; }private:int lab_id_; //实验室编号std::string lab_name_; //实验室名称int lab_max_capacity_; //实验室容量
};

Admin.h

	void init_Lab_Vector();//初始化实验室容器,用于将实验室信息读取到容器中std::vector<Laboratory> v_Lab;//实验室容器

Admin.cpp

void Admin::addLabInfo() //添加实验室信息功能实现
{int lab_id;std::string lab_name;int lab_max_capacity;std::ofstream ofs;//文件操作对象ofs.open(LABORATORY_FILE, std::ios::app);//以追加的方式写入文件if (!ofs.is_open())//文件打开失败{std::cout << "Failed to open file: " << LABORATORY_FILE << std::endl;return;}while (true) {std::cout << "Please input laboratory ID: " << std::endl;std::cin >> lab_id;bool repeat = this->checkRepeate(lab_id, 3);//检查是否有重复的实验室if (repeat){std::cout << "Laboratory ID already exists, please input again: " << std::endl;}else{break;}}std::cout << "Please input laboratory name: " << std::endl;std::cin >> lab_name;std::cout << "Please input laboratory max capacity: " << std::endl;std::cin >> lab_max_capacity;ofs << lab_id << " " << lab_name << " " << lab_max_capacity << " " << std::endl;ofs.close();std::cout << "Add laboratory information successfully!" << std::endl;this->init_Lab_Vector();system("pause");//暂停程序system("cls");//清屏
}

⑤显示实验室信息功能——showLabInfo()

对实验室容器(std::vector<Laboratory> v_Lab)进行遍历输出一下即可

Admin.cpp

void printLab(Laboratory& lab) 
{std::cout << "Laboratory ID: " << lab.get_lab_id() << ", Name: " << lab.get_lab_name() << ", Max capacity: " << lab.get_lab_max_capacity() << std::endl;
}
void Admin::showLabInfo() //查看实验室信息功能实现
{std::cout << "Laboratory information:" << std::endl;std::for_each(v_Lab.begin(), v_Lab.end(), printLab);/* 和for_each的用法一样,二选一即可for (std::vector<Laboratory>::iterator it = v_Lab.begin(); it != v_Lab.end(); it++){std::cout << "Laboratory ID: " << it->get_lab_id() << ", Name: " << it->get_lab_name() << ", Max capacity: " << it->get_lab_max_capacity() << std::endl;}*/system("pause");//暂停程序system("cls");//清屏
}

⑥清空预约记录功能——cleanRecord()

trunc方式读取打开文件即可,trunc方式可以将文件清空重新追加
用户输入Y/y表示确认删除,输入N/n表示去掉操作

Admin.cpp

void Admin::cleanRecord() //清空预约记录功能实现
{while (true) {std::cout << "Are you sure to clean all the record? (Y/N)" << std::endl;std::ofstream ofs;char choice;std::cin >> choice;if (choice == 'Y' || choice == 'y'){ofs.open(ORDER_FILE, std::ios::trunc);if (!ofs.is_open()){std::cout << "Failed to open file: " << ORDER_FILE << std::endl;break;}ofs.close();std::cout << "Clean record successfully!" << std::endl;system("pause");//暂停程序system("cls");//清屏break;}else if (choice == 'N' || choice == 'n'){std::cout << "Cancel operation!" << std::endl;system("pause");//暂停程序system("cls");//清屏break;}else{std::cout << "Invalid input, please try again." << std::endl;system("pause");//暂停程序	}}
}

6,学生模块

①登录和注销功能——studentMenu()

Student类的有参构造函数中进行学生信息的初始化操作

Student.cpp

Student::Student(int id,std::string name,std::string pwd) 
{this->setId(id);this->setName(name);this->setPwd(pwd);
}

main.cpp中定义全局函数studentMenu(),学生登录成功之后进入页面,进行相应的功能的选择
main.cpp中的用户登录函数Login()中,用户登录成功进入到学生功能页面(调用StudentMenu()函数即可)

main.cpp

//学生身份菜单界面
void StudentMenu(Identify*& identify_p) //传入父类的指针
{//进入菜单界面while(true){//调用管理员子菜单identify_p->selectMenu();//这是父类指针,只能调用公共的接口纯虚函数//想要调用子类特有的接口,需要把父类指针转回去,将父类的指针转为子类的指针Student* student = (Student*)identify_p;int userselect = 0;//用户的选择std::cin >> userselect;//接收用户的选择if (userselect == 1) //申请实验室预约{std::cout << "Your select is apply for lab appointment" << std::endl;student->applyOrder();}else if (userselect == 2) //查看自身预约信息{std::cout << "Your select is view your appointment information" << std::endl;student->showMyOrder();}else if (userselect == 3) //查看所有的实验室预约信息{std::cout << "Your select is view all appointment information" << std::endl;student->showAllOrder();}else if (userselect == 4) //取消实验室预约{std::cout << "Your select is cancel lab appointment" << std::endl;student->cancelOrder();}else //选成其他选项,默认代表注销登录{delete student;//销毁堆区创建的对象std::cout << "The logout is successful" << std::endl;system("pause");system("cls");return;}}
}

定义全局函数StudentMenu()用于显示学生身份菜单界面
Login()登录全局函数中进行调用即可
在这里插入图片描述

②申请实验室预约功能——applyOrder()

学生申请实验室预约需要的流程:选择日期(周一至周五)、选择时间段(上午、下午)、选择实验室、生成预约记录
在选择实验室的时候,需要让学生知道都有哪些实验室可以预约
Student.h中添加实验室容器std::vector<Laboratory> v_Lab,并且在有参构造中读取实验室信息文件并放到实验室容器v_Lab中,就可以申请实验室预约了

Student.h

	std::vector<Laboratory> v_Lab;//学生所申请的实验室

Student.cpp

#include "Student.h"
Student::Student() {}Student::Student(int id,std::string name,std::string pwd) 
{this->setId(id);this->setName(name);this->setPwd(pwd);std::ifstream ifs;ifs.open(LABORATORY_FILE, std::ios::in);if (!ifs.is_open()){std::cout << "Error: can not open file " << LABORATORY_FILE << std::endl;return;}Laboratory lab;int lab_id;std::string lab_name;int lab_max_capacity;while (ifs >> lab_id && ifs >> lab_name && ifs >> lab_max_capacity){lab.set_lab_id(lab_id);lab.set_lab_name(lab_name);lab.set_lab_max_capacity(lab_max_capacity);this->v_Lab.push_back(lab);}ifs.close();
}void Student::selectMenu()//功能菜单实现
{std::cout << "Welcome student: " << this->getName() << "login!" << std::endl;std::cout << "\t\t ----------------------------------\n";std::cout << "\t\t|          1.applyOrder           |\n";std::cout << "\t\t|          2.showMyOrder          |\n";std::cout << "\t\t|          3.showAllOrder         |\n";std::cout << "\t\t|          4.cancelOrder          |\n";std::cout << "\t\t|          0 or OtherKey.logout   |\n";std::cout << "\t\t ----------------------------------\n";std::cout << "Please select your action: " << std::endl;
}
void Student::applyOrder() //预约申请实现
{int day;int time_slot;int lab_id;while (true) {std::cout << "The lab is open Monday to Friday!" << std::endl;std::cout << "Please enter the time to request an appointment:" << std::endl;std::cout << "1, Monday" << std::endl;std::cout << "2, Tuesday" << std::endl;std::cout << "3, Wednesday" << std::endl;std::cout << "4, Thursday" << std::endl;std::cout << "5, Friday" << std::endl;std::cin >> day;if (day < 1 || day>5){std::cout << "Invalid input!" << std::endl;std::cout << "-------------------" << std::endl;}else{break;}}while (true){std::cout << "Please enter the time slot for requesting an appointment:" << std::endl;std::cout << "1, Morning 8:00-12:00" << std::endl;std::cout << "2, Afternoon 13:00-17:00" << std::endl;std::cout << "3, Evening 18:00-22:00" << std::endl;std::cin >> time_slot;if (time_slot < 1 || time_slot>3){std::cout << "Invalid input!" << std::endl;std::cout << "-------------------" << std::endl;}else{break;}}while (true) {std::cout << "Please select a laboratory:" << std::endl;for (int i = 0; i < this->v_Lab.size(); i++){std::cout << i + 1 << ". " << this->v_Lab[i].get_lab_name() << " (Capacity: " << this->v_Lab[i].get_lab_max_capacity() << ")" << std::endl;}std::cin >> lab_id;if (lab_id < 1 || lab_id>this->v_Lab.size()){std::cout << "Invalid input!" << std::endl;std::cout<<"-------------------"<<std::endl;}else{break;}}std::cout<<"The appointment application is successful! Wait for the lab teacher to review it."<<std::endl;std::ofstream ofs;ofs.open(ORDER_FILE, std::ios::app);if (!ofs.is_open()){std::cout << "Error: can not open file " << ORDER_FILE << std::endl;return;}ofs << "day:" << day << " ";ofs<<"time_slot:" << time_slot << " " ;ofs<<"student_id:" << this->getId() << " " ;ofs<<"student_name:"<<this->getName()<<" " ;ofs<<"lab_id:"<<lab_id<<" " ;ofs<<"lab_name:"<<this->v_Lab[lab_id-1].get_lab_name()<<" " ;ofs<<"status:"<<1<<std::endl;//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消ofs.close();system("pause");system("cls");}
void Student::showMyOrder() {}//显示我的预约
void Student::showAllOrder() {}//显示所有预约
void Student::cancelOrder() {}//取消预约

③显示我的预约功能——showMyOrder()

首先创建实验室预约文件LabAppointments.hLabAppointments.cpp
实验室预约文件类LabAppointments中含有更新预约记录成员函数updateAppointments(),记录所有实验室预约记录的容器map<int, std::map<std::string, std::string>> v_Appointments,统计实验室预约记录条数appointments_size_

LabAppointments.h

#pragma once
#include <map>
#include <iostream>
#include <fstream>
#include "globalFile.h"
#include <map>
class LabAppointments
{
public:LabAppointments();void updateAppointments();//更新预约记录信息std::map<int,std::map<std::string, std::string>> v_Appointments;//记录所有预约记录信息,key为预约记录的总条数,value为对应预约记录信息private:int appointments_size_;//预约记录的总条数
};

LabAppointments.cpp

#include "LabAppointments.h"LabAppointments::LabAppointments() 
{std::ifstream ifs;ifs.open(ORDER_FILE,std::ios::in);if(!ifs.is_open()){std::cout << "Error: Failed to open file " << ORDER_FILE << std::endl;return;}//为了解析方便,这里都使用string类型存储std::string day;//1-5 represent Monday to Fridaystd::string time_slot;//1-3 represent 8:00-12:00,13:00-17:00,18:00-22:00std::string student_id;//预约实验室申请的学生编号std::string student_name;//预约实验室申请的学生姓名std::string lab_id;//实验室编号std::string lab_name;//实验室名称std::string status;//预约申请的状态,1表示待审核状态this->appointments_size_ = 0;//预约申请的数量while (ifs >> day && ifs >> time_slot && ifs >> student_id && ifs >> student_name && ifs >> lab_id && ifs >> lab_name && ifs >> status){/*std::cout << day << std::endl;std::cout << time_slot << std::endl;std::cout << student_id << std::endl;std::cout << student_name << std::endl;std::cout << lab_id << std::endl;std::cout << lab_name << std::endl;std::cout << status << std::endl;std::cout << std::endl;*//*解析内容如下:day:1time_slot:1student_id:1student_name:977lab_id:4lab_name:QTstatus:1*/std::string key;std::string value;std::map<std::string, std::string> m;//存放key和value//day:1int pos = day.find(':');//pos=3if (pos != -1) //找到冒号了{key = day.substr(0, pos);//dayvalue = day.substr(pos + 1, day.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//time_slot:1pos = time_slot.find(':');if (pos != -1) //找到冒号了{key = time_slot.substr(0, pos);//time_slotvalue = time_slot.substr(pos + 1, time_slot.size() - pos - 1);m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//student_id:1pos = student_id.find(':');if (pos != -1) //找到冒号了{key = student_id.substr(0, pos);//student_idvalue = student_id.substr(pos + 1, student_id.size() - pos - 1);m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//student_name:977pos = student_name.find(':');if (pos != -1) //找到冒号了{key = student_name.substr(0, pos);//student_namevalue = student_name.substr(pos + 1, student_name.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//lab_id:4pos = lab_id.find(':');if (pos != -1) //找到冒号了{key = lab_id.substr(0, pos);//lab_idvalue = lab_id.substr(pos + 1, lab_id.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//lab_name:QTpos = lab_name.find(':');if (pos != -1) //找到冒号了{key = lab_name.substr(0, pos);//lab_namevalue = lab_name.substr(pos + 1, lab_name.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//status:1pos = status.find(':');if (pos != -1) //找到冒号了{key = status.substr(0, pos);value = status.substr(pos + 1, status.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//将map中的内容存入Appointment对象中this->v_Appointments.insert(std::make_pair(this->appointments_size_, m));this->appointments_size_++;}ifs.close();//测试/*for (std::map<int, std::map<std::string, std::string>>::iterator it = this->v_Appointments.begin(); it != this->v_Appointments.end(); it++){std::cout << "Number of laboratory reservation records: " << it->first << ", Value is: " << std::endl;for (std::map<std::string, std::string>::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++){std::cout << it2->first << ":" << it2->second << " ";}std::cout << std::endl;}*/
}void LabAppointments::updateAppointments() //实验室预约申请状态更新
{if (this->appointments_size_ == 0) //一条实验室预约记录都没有{return;}std::ofstream ofs;//写入到文件中ofs.open(ORDER_FILE, std::ios::out | std::ios::trunc);//对实验室预约记录文件进行重写覆盖写入if (!ofs.is_open()){std::cout << "Error: Failed to open file " << ORDER_FILE << std::endl;return;}for (int i=0;i<this->appointments_size_;i++){	//v_Appointments[i]第i条实验室预约记录,是一个map//v_Appointments[i]["day"]第i条实验室预约记录的日期,通过这个map的key("day")拿到对应的valueofs << "day:" << this->v_Appointments[i]["day"] << " ";ofs << "time_slot:" << this->v_Appointments[i]["time_slot"] << " ";ofs << "student_id:" << this->v_Appointments[i]["student_id"] << " ";ofs << "student_name:" << this->v_Appointments[i]["student_name"] << " ";ofs << "lab_id:" << this->v_Appointments[i]["lab_id"] << " ";ofs << "lab_name:" << this->v_Appointments[i]["lab_name"] << " ";ofs << "status:" << this->v_Appointments[i]["status"] << std::endl;}ofs.close();
}

接下来开始实现显示我的预约操作
实验室预约记录order.txt中有三条实验室预约记录
在这里插入图片描述
先创建一个LabAppointments对象,看下它有几条预约记录(appointments_size_),若为0,则没有实验室申请预约记录;若有记录,则遍历所有的实验室预约记录,然后以学号(student_id_)为判断记录进行显示即可
显示内容:哪一天、时间段、实验室编号、实验室名称、状态,不需要显示学号和学生姓名
Student.cpp

void Student::showMyOrder() //显示我的预约
{int number{0};//实验室申请记录条数LabAppointments appointments;//预约信息if (appointments.getAppointments() == 0)//如果没有预约信息{std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}for (int i = 0; i < appointments.getAppointments(); i++) {//this->getId()                                                   是一个int类型//appointments.v_Appointments[i]["student_id"]                    是一个string类型//appointments.v_Appointments[i]["student_id"].c_str()            是一个char*类型,是C语言的字符串;.c_str()将string 转 const char*//atoi(appointments.v_Appointments[i]["student_id"].c_str())      是一个int类型,是C语言的整数;      atoi()将const char* 转 int//所以可以比较两个string类型的值if (std::atoi(appointments.v_Appointments[i]["student_id"].c_str()) == this->getId())//如果是自己的预约{number++;std::cout << "Your appointment is the day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1"?"Morning":(appointments.v_Appointments[i]["time_slot"] == "2")?"Afternoon":(appointments.v_Appointments[i]["time_slot"] == "3")?"Evening":"Your Appointment Time Slot Is Error.");std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; statis: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1"){status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2"){status += "Approved";}else if (appointments.v_Appointments[i]["status"] == "3"){status += "Rejected";}else if (appointments.v_Appointments[i]["status"] == "4"){status += "Canceled";}else{status += "Your Appointment Status Is Error.";}std::cout << " " << status << std::endl;}}std::cout << "Total " << number << " LabAppointments Appointment!" << std::endl;system("pause");system("cls");
}

④查看所有预约功能——showAllOrder()

和显示我的预约功能类似,显示内容:哪一天、时间段、学号、学生姓名、实验室编号、实验室名称、预约状态
比显示我的预约功能多了显示学号、学生姓名,优化一点,为每条实验室申请预约记录加个序号

Student.cpp

void Student::showAllOrder() //显示所有预约
{LabAppointments appointments;if (appointments.getAppointments() == 0){std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}for (int i = 0; i < appointments.getAppointments(); i++){std::cout << i + 1 << ".";std::cout << "The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1"?"Morning":(appointments.v_Appointments[i]["time_slot"] == "2")?"Afternoon":(appointments.v_Appointments[i]["time_slot"] == "3")?"Evening":"Your Appointment Time Slot Is Error.");std::cout << "; student_id is: " << appointments.v_Appointments[i]["student_id"];std::cout << "; student_name is: " << appointments.v_Appointments[i]["student_name"];std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; statis: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1"){status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2"){status += "Approved";}else if (appointments.v_Appointments[i]["status"] == "3"){status += "Rejected";}else if (appointments.v_Appointments[i]["status"] == "4"){status += "Canceled";}else{status += "Your Appointment Status Is Error.";}std::cout << " " << status << std::endl;}system("pause");system("cls");
}

⑤取消预约功能——cancelOrder()

只有在自己的学号并且预约成功或审核中才可以取消预约
1表示审核中,2表示已通过,3表示已拒绝,4表示已取消

Student.cpp

void Student::cancelOrder() //取消预约
{LabAppointments appointments;if (appointments.getAppointments() == 0) {std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}std::cout << "Records that are under review or have a successful appointment can be canceled, so please enter the canceled record:" << std::endl;std::vector<int> v_index;int index = 1;for (int i = 0; i < appointments.getAppointments(); i++){if (atoi(appointments.v_Appointments[i]["student_id"].c_str()) == this->getId())//是自己的预约{if (appointments.v_Appointments[i]["status"] == "1" || appointments.v_Appointments[i]["status"] == "2")//审核中或已通过的预约可以取消{v_index.push_back(i);std::cout << index << ". ";std::cout <<" The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1"?"Morning":(appointments.v_Appointments[i]["time_slot"] == "2")?"Afternoon":(appointments.v_Appointments[i]["time_slot"] == "3")?"Evening":"Your Appointment Time Slot Is Error.");std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; statis: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1")//审核中{status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2")//已通过{status += "Approved";}std::cout << " " << status << std::endl;index++;}}}std::cout << "Please enter the index of the canceled record, or enter 0 to return:" << std::endl;int select = 0;while (true){std::cin >> select;if (select >= 0 && select <= v_index.size()){if (select == 0) //输入0表示取消{break;}else {int i = v_index[select - 1];appointments.v_Appointments[i]["status"] = "4";//将状态设置为已取消appointments.updateAppointments();std::cout << "The appointment has been canceled successfully!" << std::endl;break;}}std::cout << "You have made a mistake, please re-enter." << std::endl;}system("pause");system("cls");
}

7,教师模块

①登录和注销功能——TeacherMenu()

Teacher类的有参构造函数中进行学生信息的初始化操作

Teacher.cpp

Teacher::Teacher(int teacher_id,std::string name,std::string pwd) 
{//初始化实验室教师职工号、姓名、密码this->setId(teacher_id);this->setName(name);this->setPwd(pwd);
}

main.cpp中定义全局函数teacherMenu(),实验室教师登录成功之后进入页面,进行相应的功能的选择
main.cpp中的用户登录函数Login()中,用户登录成功进入到实验室教师功能页面(调用TeacherMenu()函数即可)

main.cpp

void TeacherMenu(Identify*& identify_p) //传入父类的指针
{//进入菜单界面while (true){//调用管理员子菜单identify_p->selectMenu(); //这是父类指针,只能调用公共的接口纯虚函数Teacher* teacher = (Teacher*)identify_p; //将父类指针转为子类指针int userselect = 0; //用户的选择std::cin >> userselect; //接收用户的选择if (userselect == 1) {std::cout << "Your select is view all appointment information" << std::endl;teacher->showAllOrder();}else if (userselect == 2){std::cout << "Your select is valid appointment information" << std::endl;teacher->validOrder();}else//选成其他选项,默认代表注销登录{delete teacher; //销毁堆区创建的对象std::cout << "The logout is successful" << std::endl;system("pause");system("cls");return;}}
}

定义全局函数TeacherMenu()用于显示学生身份菜单界面
Login()登录全局函数中进行调用即可
在这里插入图片描述

②查看所有预约功能——showAllOrder()

与学生身份的查看所有预约功能相似,用于显示所有预约记录

Teacher.cpp

void Teacher::showAllOrder()//显示所有预约
{LabAppointments appointments;if (appointments.getAppointments() == 0){std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}for (int i = 0; i < appointments.getAppointments(); i++){std::cout << i + 1 << ".";std::cout << "The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1" ? "Morning" : (appointments.v_Appointments[i]["time_slot"] == "2") ? "Afternoon" : (appointments.v_Appointments[i]["time_slot"] == "3") ? "Evening" : "Your Appointment Time Slot Is Error.");std::cout << "; student_id is: " << appointments.v_Appointments[i]["student_id"];std::cout << "; student_name is: " << appointments.v_Appointments[i]["student_name"];std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; status: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1"){status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2"){status += "Approved";}else if (appointments.v_Appointments[i]["status"] == "3"){status += "Rejected";}else if (appointments.v_Appointments[i]["status"] == "4"){status += "Canceled";}else{status += "Your Appointment Status Is Error.";}std::cout << " " << status << std::endl;}system("pause");system("cls");
}

③审核预约功能——validOrder()

获取实验室预约记录order.txt中所有数据,筛选status为待审核状态的进行显示
实验室老师对这些待审核状态的实验室预约记录进行审核,审核完成之后重新更新状态即可

Teacher.cpp

void Teacher::validOrder() //审核预约
{LabAppointments appointments;if (appointments.getAppointments() == 0){std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}std::cout << "The records of laboratory appointments to be reviewed are as follows:" << std::endl;std::vector<int> v_valid_order;int index = 1;for (int i = 0; i < appointments.getAppointments(); i++){if (appointments.v_Appointments[i]["status"] == "1")//1表示审核中{v_valid_order.push_back(i);std::cout << index++ << ".";std::cout << "The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1" ? "Morning" : (appointments.v_Appointments[i]["time_slot"] == "2") ? "Afternoon" : (appointments.v_Appointments[i]["time_slot"] == "3") ? "Evening" : "Your Appointment Time Slot Is Error.");std::cout << "; student_id is: " << appointments.v_Appointments[i]["student_id"];std::cout << "; student_name is: " << appointments.v_Appointments[i]["student_name"];std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; status: Pending Revie";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消std::cout << status << std::endl;}}//输入审核的实验室预约序号,0表示返回,不想审核了std::cout << "Please enter the lab appointment record you want to review, 0 means return" << std::endl;int select = 0;//实验室教师选择要审核的预约序号int ret = 0;//接收实验室教师给的审核结果,1表示审核通过,2表示审核拒绝while (true){std::cin >> select;if (select >= 0 && select <= v_valid_order.size()){if (select == 0)//选择0,表示不想审核了,退出循环即可{break;}else{//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消std::cout << "Please enter the result of the review" << std::endl;std::cout << "1. Approved" << std::endl;std::cout << "2. Rejected" << std::endl;std::cin >> ret;if (ret == 1){appointments.v_Appointments[v_valid_order[select - 1]]["status"] = "2";}else if (ret == 2){appointments.v_Appointments[v_valid_order[select - 1]]["status"] = "3";}else{std::cout << "Your input is error!" << std::endl;continue;}appointments.updateAppointments();//更新预约信息到文件中std::cout << "The review result has been saved!" << std::endl;break;}}std::cout << "You have made a mistake, please re-enter." << std::endl;}system("pause");system("cls");
}

四、完整代码

0,项目结构

在这里插入图片描述
项目同级目录下创建五个文本充当数据库
在这里插入图片描述

1,globalFile.h

宏定义,确定五个配置文件

#pragma once //管理员文件
#define ADMIN_FILE     "admin.txt"
//学生文件
#define STUDENT_FILE   "student.txt"
//教师文件
#define TEACHER_FILE   "teacher.txt"
//实验室信息文件
#define LABORATORY_FILE  "laboratoryRoom.txt"
//订单文件
#define ORDER_FILE     "order.txt"

2,Identify.h

管理员、学生、老师的基类

#pragma once
#include <iostream>
class Identify 
{
public:virtual void selectMenu() = 0;//纯虚函数,不同用户登录成功之后显示的菜单均不同std::string getName() {return this->name_;}std::string getPwd(){return this->pwd_;}void setName(std::string name){this->name_ = name;}void setPwd(std::string pwd){this->pwd_ = pwd;}private:std::string name_;//姓名std::string pwd_;//密码
};

3,Laboratory.h

实验室类

#pragma once
#include <iostream>//实验室类
class Laboratory
{
public:Laboratory() {};Laboratory(int id, std::string name, int capacity):lab_id_(id), lab_name_(name), lab_max_capacity_(capacity) {}void set_lab_id(int id) { this->lab_id_ = id; }void set_lab_name(std::string name) { this->lab_name_ = name; }void set_lab_max_capacity(int capacity) { this->lab_max_capacity_ = capacity; }int get_lab_id() const { return this->lab_id_; }std::string get_lab_name() const { return this->lab_name_; }int get_lab_max_capacity() const { return this->lab_max_capacity_; }private:int lab_id_; //实验室编号std::string lab_name_; //实验室名称int lab_max_capacity_; //实验室容量
};

4,Admin.h

#pragma once
#include <iostream>
#include <fstream>
#include "globalFile.h"
#include "Identify.h"
#include <vector>
#include "Student.h"
#include "Teacher.h"
#include <algorithm>
#include "Laboratory.h"class Admin:public Identify
{
public:Admin();Admin(std::string name,std::string pwd);virtual void Identify::selectMenu() override;//功能菜单实现void addUser();//添加用户void showUser();//查看用户void addLabInfo();//添加实验室信息void showLabInfo();//查看实验室信息void cleanRecord();//清空预约记录void init_Stu_Tea_Vector();//初始化容器,用于将对应的文本文件信息读取到对应的容器中std::vector<Student> v_Student;//学生容器std::vector<Teacher> v_Teacher;//教师容器bool checkRepeate(int id, int type);//检查学号\职工号\实验室编号是否重复void init_Lab_Vector();//初始化实验室容器,用于将实验室信息读取到容器中std::vector<Laboratory> v_Lab;//实验室容器
};

5,Admin.cpp

#include "Admin.h"
Admin::Admin() {}Admin::Admin(std::string name, std::string pwd) 
{//初始化管理员信息Admin::setName(name);Admin::setPwd(pwd);//初始化学生和老师的容器,获取文件中所有老师和学生的信息this->init_Stu_Tea_Vector();//初始化实验室的容器,获取文件中所有实验室的信息this->init_Lab_Vector();
}void Admin::selectMenu()//功能菜单实现
{std::cout << "Welcome admin: " << this->getName() << " login!" << std::endl;std::cout << "\t\t --------------------------------\n";std::cout << "\t\t|          1.addUser             |\n";std::cout << "\t\t|          2.showUser            |\n";std::cout << "\t\t|          3.addLabInfo          |\n";std::cout << "\t\t|          4.showLabInfo         |\n";std::cout << "\t\t|          5.cleanRecord         |\n";std::cout << "\t\t|          0 or OtherKey.logout  |\n";std::cout << "\t\t --------------------------------\n";std::cout << "Please select your action: " << std::endl;
}void Admin::addUser()添加用户功能实现 
{std::string fileType;//根据用户的选择进行操作不同的文件std::string tip;//提示是学号还是职工号std::string repeat_tip;//重复提示信息std::ofstream ofs;//文件操作对象int userselect = 0;//获取用户的选择while (true){//提示用户std::cout << "Please enter the type of account you want to add (1.student or 2.teacher):" << std::endl;std::cout << "1、student" << std::endl;std::cout << "2、teacher" << std::endl;std::cout << "0、exit" << std::endl;std::cin >> userselect;if (userselect == 1)//添加学生{fileType = STUDENT_FILE;tip = "please input studentID: ";repeat_tip = "studentID already exists, please input again: ";break;}else if (userselect == 2)//添加老师{fileType = TEACHER_FILE;tip = "please input teacherID: ";repeat_tip = "teacherID already exists, please input again: ";break;}else if(userselect == 0){system("cls");//清屏return;}else {std::cout << "Invalid input, please try again." << std::endl;}}ofs.open(fileType, std::ios::app);//以追加的方式写入文件if (!ofs.is_open())//文件打开失败{std::cout << "Failed to open file: " << fileType << std::endl;return;}int id;//学号或职工号std::string name;//姓名std::string pwd;//密码std::cout << tip << std::endl;//提示输入学号或职工号while (true) {std::cin >> id;bool repeat = this->checkRepeate(id, userselect);//检查是否有重复的用户if (repeat)//有重复的用户{std::cout << repeat_tip << std::endl;}else//没有重复的用户{break;}}std::cout << "please input name: " << std::endl;std::cin >> name;//输入姓名std::cout << "please input password: " << std::endl;std::cin >> pwd;//输入密码//写入文件ofs << id << " " << name << " " << pwd << " " << std::endl;ofs.close();std::cout << "Add user successfully!" << std::endl;this->init_Stu_Tea_Vector();//刷新容器,重新读取文件中的用户信息system("pause");//暂停程序system("cls");//清屏}void Admin::init_Stu_Tea_Vector()//初始化学生和老师的容器,用于存放从文件中读取的所有用户信息
{//对容器进行初始化,清空用于存放对应用户信息的容器this->v_Student.clear();this->v_Teacher.clear();std::ifstream ifs;//文件读取操作对象//读取学生信息ifs.open(STUDENT_FILE, std::ios::in);//以读取的方式打开学生文件if (!ifs.is_open())//文件打开失败{std::cout << "Failed to open file: " << STUDENT_FILE << std::endl;return;}Student student;int student_id;std::string student_name;std::string student_pwd;while (ifs >> student_id && ifs >> student_name && ifs >> student_pwd){student.setId(student_id);student.setName(student_name);student.setPwd(student_pwd);v_Student.push_back(student);}//std::cout << "Read student information successfully!" << std::endl;//std::cout<<"Student size: "<<v_Student.size()<<std::endl;ifs.close();//读取老师信息ifs.open(TEACHER_FILE, std::ios::in);//以读取的方式打开老师文件if (!ifs.is_open())//文件打开失败{std::cout << "Failed to open file: " << TEACHER_FILE << std::endl;return;}Teacher teacher;int teacher_id;std::string teacher_name;std::string teacher_pwd;while (ifs >> teacher_id && ifs >> teacher_name && ifs >> teacher_pwd){teacher.setId(teacher_id);teacher.setName(teacher_name);teacher.setPwd(teacher_pwd);v_Teacher.push_back(teacher);}//std::cout << "Read teacher information successfully!" << std::endl;//std::cout << "Teacher size: " << v_Teacher.size() << std::endl;ifs.close();
}bool Admin::checkRepeate(int id,int fileType)//检查是否有重复的用户
{if (fileType == 1)//学生{for (int i = 0; i < v_Student.size(); i++){if (v_Student[i].getId() == id){return true;}}}else if (fileType == 2)//老师{for (int i = 0; i < v_Teacher.size(); i++){if (v_Teacher[i].getId() == id){return true;}}}else if (fileType == 3) //实验室{for (int i = 0; i < v_Lab.size(); i++){if (v_Lab[i].get_lab_id() == id){return true;}}}return false;
}void printStudent(Student& student)
{std::cout << "Student ID: " << student.getId() << ", Name: "<<student.getName() << ", Password: " << student.getPwd() << std::endl;
}void printTeacher(Teacher& teacher)
{std::cout << "Teacher ID: " << teacher.getId() << ", Name: " << teacher.getName() << ", Password: " << teacher.getPwd() << std::endl;
}void Admin::showUser() //查看用户功能实现
{while (true){std::cout << "Please enter the type of account you want to show (1.student or 2.teacher):" << std::endl;std::cout << "1、student" << std::endl;std::cout << "2、teacher" << std::endl;std::cout << "0、exit" << std::endl;int userselect = 0;std::cin >> userselect;if (userselect == 1)//查看所有学生的信息{std::cout << "Student information:" << std::endl;std::for_each(v_Student.begin(), v_Student.end(), printStudent);/* 和for_each的用法一样,二选一即可for(std::vector<Student>::iterator it=v_Student.begin();it!=v_Student.end();it++){std::cout<<"Student ID: "<<it->getId()<<", Name: "<<it->getName()<<", Password: "<<it->getPwd()<<std::endl;}*/system("pause");//暂停程序system("cls");//清屏break;}else if (userselect == 2)//查看所有老师的信息{std::cout << "Teacher information:" << std::endl;std::for_each(v_Teacher.begin(), v_Teacher.end(), printTeacher);/* 和for_each的用法一样,二选一即可for (std::vector<Teacher>::iterator it = v_Teacher.begin(); it != v_Teacher.end(); it++){std::cout << "Teacher ID: " << it->getId() << ", Name: " << it->getName() << ", Password: " << it->getPwd() << std::endl;}*/system("pause");//暂停程序system("cls");//清屏break;}else if (userselect == 0)//退出{system("cls");//清屏break;}else{std::cout << "Invalid input, please try again." << std::endl;system("pause");//暂停程序system("cls");//清屏}}
}void Admin::addLabInfo() //添加实验室信息功能实现
{int lab_id;std::string lab_name;int lab_max_capacity;std::ofstream ofs;//文件操作对象ofs.open(LABORATORY_FILE, std::ios::app);//以追加的方式写入文件if (!ofs.is_open())//文件打开失败{std::cout << "Failed to open file: " << LABORATORY_FILE << std::endl;return;}while (true) {std::cout << "Please input laboratory ID: " << std::endl;std::cin >> lab_id;bool repeat = this->checkRepeate(lab_id, 3);//检查是否有重复的实验室if (repeat){std::cout << "Laboratory ID already exists, please input again: " << std::endl;}else{break;}}std::cout << "Please input laboratory name: " << std::endl;std::cin >> lab_name;std::cout << "Please input laboratory max capacity: " << std::endl;std::cin >> lab_max_capacity;ofs << lab_id << " " << lab_name << " " << lab_max_capacity << " " << std::endl;ofs.close();std::cout << "Add laboratory information successfully!" << std::endl;this->init_Lab_Vector();system("pause");//暂停程序system("cls");//清屏
}void Admin::init_Lab_Vector() //初始化实验室信息功能实现
{//对容器进行初始化,清空用于存放实验室信息的容器this->v_Lab.clear();//读取实验室信息std::ifstream ifs;ifs.open(LABORATORY_FILE, std::ios::in);//以读取的方式打开实验室信息文件if (!ifs.is_open()) {std::cout << "Failed to open file: " << LABORATORY_FILE << std::endl;return;}Laboratory lab;int lab_id;std::string lab_name;int lab_max_capacity;while (ifs>>lab_id&&ifs>>lab_name&&ifs>>lab_max_capacity){lab.set_lab_id(lab_id);lab.set_lab_name(lab_name);lab.set_lab_max_capacity(lab_max_capacity);this->v_Lab.push_back(lab);}ifs.close();//std::cout << "Read laboratory information successfully!" << std::endl;//std::cout << "Laboratory size: " << this->v_Lab.size() << std::endl;}void printLab(Laboratory& lab) 
{std::cout << "Laboratory ID: " << lab.get_lab_id() << ", Name: " << lab.get_lab_name() << ", Max capacity: " << lab.get_lab_max_capacity() << std::endl;
}
void Admin::showLabInfo() //查看实验室信息功能实现
{std::cout << "Laboratory information:" << std::endl;std::for_each(v_Lab.begin(), v_Lab.end(), printLab);/* 和for_each的用法一样,二选一即可for (std::vector<Laboratory>::iterator it = v_Lab.begin(); it != v_Lab.end(); it++){std::cout << "Laboratory ID: " << it->get_lab_id() << ", Name: " << it->get_lab_name() << ", Max capacity: " << it->get_lab_max_capacity() << std::endl;}*/system("pause");//暂停程序system("cls");//清屏
}
void Admin::cleanRecord() //清空预约记录功能实现
{while (true) {std::cout << "Are you sure to clean all the record? (Y/N)" << std::endl;std::ofstream ofs;char choice;std::cin >> choice;if (choice == 'Y' || choice == 'y'){ofs.open(ORDER_FILE, std::ios::trunc);if (!ofs.is_open()){std::cout << "Failed to open file: " << ORDER_FILE << std::endl;break;}ofs.close();std::cout << "Clean record successfully!" << std::endl;system("pause");//暂停程序system("cls");//清屏break;}else if (choice == 'N' || choice == 'n'){std::cout << "Cancel operation!" << std::endl;system("pause");//暂停程序system("cls");//清屏break;}else{std::cout << "Invalid input, please try again." << std::endl;system("pause");//暂停程序}}
}

6,LabAppointments.h

实验室预约申请类,存放学生的预约申请实验室记录

#pragma once
#include <map>
#include <iostream>
#include <fstream>
#include "globalFile.h"
#include <map>
class LabAppointments
{
public:LabAppointments();void updateAppointments();//更新预约记录信息std::map<int,std::map<std::string, std::string>> v_Appointments;//记录所有预约记录信息,key为预约记录的总条数,value为对应预约记录信息int getAppointments() //获取预约记录信息{return this->appointments_size_;}void setAppointments(int size) //设置预约记录信息{this->appointments_size_ = size;}
private:int appointments_size_;//预约记录的总条数
};

7,LabAppointments.cpp

#include "LabAppointments.h"LabAppointments::LabAppointments() 
{std::ifstream ifs;ifs.open(ORDER_FILE,std::ios::in);if(!ifs.is_open()){std::cout << "Error: Failed to open file " << ORDER_FILE << std::endl;return;}//为了解析方便,这里都使用string类型存储std::string day;//1-5 represent Monday to Fridaystd::string time_slot;//1-3 represent 8:00-12:00,13:00-17:00,18:00-22:00std::string student_id;//预约实验室申请的学生编号std::string student_name;//预约实验室申请的学生姓名std::string lab_id;//实验室编号std::string lab_name;//实验室名称std::string status;//预约申请的状态,1表示待审核状态this->appointments_size_ = 0;//预约申请的数量while (ifs >> day && ifs >> time_slot && ifs >> student_id && ifs >> student_name && ifs >> lab_id && ifs >> lab_name && ifs >> status){/*std::cout << day << std::endl;std::cout << time_slot << std::endl;std::cout << student_id << std::endl;std::cout << student_name << std::endl;std::cout << lab_id << std::endl;std::cout << lab_name << std::endl;std::cout << status << std::endl;std::cout << std::endl;*//*解析内容如下:day:1time_slot:1student_id:1student_name:977lab_id:4lab_name:QTstatus:1*/std::string key;std::string value;std::map<std::string, std::string> m;//存放key和value//day:1int pos = day.find(':');//pos=3if (pos != -1) //找到冒号了{key = day.substr(0, pos);//dayvalue = day.substr(pos + 1, day.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//time_slot:1pos = time_slot.find(':');if (pos != -1) //找到冒号了{key = time_slot.substr(0, pos);//time_slotvalue = time_slot.substr(pos + 1, time_slot.size() - pos - 1);m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//student_id:1pos = student_id.find(':');if (pos != -1) //找到冒号了{key = student_id.substr(0, pos);//student_idvalue = student_id.substr(pos + 1, student_id.size() - pos - 1);m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//student_name:977pos = student_name.find(':');if (pos != -1) //找到冒号了{key = student_name.substr(0, pos);//student_namevalue = student_name.substr(pos + 1, student_name.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//lab_id:4pos = lab_id.find(':');if (pos != -1) //找到冒号了{key = lab_id.substr(0, pos);//lab_idvalue = lab_id.substr(pos + 1, lab_id.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//lab_name:QTpos = lab_name.find(':');if (pos != -1) //找到冒号了{key = lab_name.substr(0, pos);//lab_namevalue = lab_name.substr(pos + 1, lab_name.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//status:1pos = status.find(':');if (pos != -1) //找到冒号了{key = status.substr(0, pos);value = status.substr(pos + 1, status.size() - pos - 1);//1m.insert(std::pair<std::string, std::string>(key, value));//插入到map中}//将map中的内容存入Appointment对象中this->v_Appointments.insert(std::make_pair(this->appointments_size_, m));this->appointments_size_++;}ifs.close();//测试/*for (std::map<int, std::map<std::string, std::string>>::iterator it = this->v_Appointments.begin(); it != this->v_Appointments.end(); it++){std::cout << "Number of laboratory reservation records: " << it->first << ", Value is: " << std::endl;for (std::map<std::string, std::string>::iterator it2 = it->second.begin(); it2 != it->second.end(); it2++){std::cout << it2->first << ":" << it2->second << " ";}std::cout << std::endl;}*/
}void LabAppointments::updateAppointments() //实验室预约申请状态更新
{if (this->appointments_size_ == 0) //一条实验室预约记录都没有{return;}std::ofstream ofs;//写入到文件中ofs.open(ORDER_FILE, std::ios::out | std::ios::trunc);//对实验室预约记录文件进行重写覆盖写入if (!ofs.is_open()){std::cout << "Error: Failed to open file " << ORDER_FILE << std::endl;return;}for (int i=0;i<this->appointments_size_;i++){	//v_Appointments[i]第i条实验室预约记录,是一个map//v_Appointments[i]["day"]第i条实验室预约记录的日期,通过这个map的key("day")拿到对应的valueofs << "day:" << this->v_Appointments[i]["day"] << " ";ofs << "time_slot:" << this->v_Appointments[i]["time_slot"] << " ";ofs << "student_id:" << this->v_Appointments[i]["student_id"] << " ";ofs << "student_name:" << this->v_Appointments[i]["student_name"] << " ";ofs << "lab_id:" << this->v_Appointments[i]["lab_id"] << " ";ofs << "lab_name:" << this->v_Appointments[i]["lab_name"] << " ";ofs << "status:" << this->v_Appointments[i]["status"] << std::endl;}ofs.close();}

8,Student.h

#pragma once
#include "Identify.h"
#include <fstream>
#include "globalFile.h"
#include "Laboratory.h"
#include <vector>
#include "LabAppointments.h"class Student:public Identify
{
public:Student();Student(int id,std::string name,std::string pwd);//学号、姓名、密码virtual void Identify::selectMenu() override;//重写基类中的虚函数void applyOrder();//申请预约功能void showMyOrder();//显示我的预约功能void showAllOrder();//查看所有预约功能void cancelOrder();//取消预约功能int getId() {return this->student_id_;}void setId(int id) {this->student_id_ = id;}std::vector<Laboratory> v_Lab;//学生所申请的实验室
private:int student_id_;
};

9,Student.cpp

#include "Student.h"
Student::Student() {}Student::Student(int id,std::string name,std::string pwd) 
{this->setId(id);this->setName(name);this->setPwd(pwd);std::ifstream ifs;//读取实验室信息ifs.open(LABORATORY_FILE, std::ios::in);if (!ifs.is_open()){std::cout << "Error: can not open file " << LABORATORY_FILE << std::endl;return;}Laboratory lab;int lab_id;std::string lab_name;int lab_max_capacity;while (ifs >> lab_id && ifs >> lab_name && ifs >> lab_max_capacity){lab.set_lab_id(lab_id);lab.set_lab_name(lab_name);lab.set_lab_max_capacity(lab_max_capacity);this->v_Lab.push_back(lab);}ifs.close();
}void Student::selectMenu()//功能菜单实现
{std::cout << "Welcome student: " << this->getName() << "login!" << std::endl;std::cout << "\t\t ----------------------------------\n";std::cout << "\t\t|          1.applyOrder           |\n";std::cout << "\t\t|          2.showMyOrder          |\n";std::cout << "\t\t|          3.showAllOrder         |\n";std::cout << "\t\t|          4.cancelOrder          |\n";std::cout << "\t\t|          0 or OtherKey.logout   |\n";std::cout << "\t\t ----------------------------------\n";std::cout << "Please select your action: " << std::endl;
}void Student::applyOrder() //预约申请实现
{int day;int time_slot;int lab_id;while (true) {std::cout << "The lab is open Monday to Friday!" << std::endl;std::cout << "Please enter the time to request an appointment:" << std::endl;std::cout << "1, Monday" << std::endl;std::cout << "2, Tuesday" << std::endl;std::cout << "3, Wednesday" << std::endl;std::cout << "4, Thursday" << std::endl;std::cout << "5, Friday" << std::endl;std::cin >> day;if (day < 1 || day>5){std::cout << "Day is invalid input!" << std::endl;std::cout << "-------------------" << std::endl;}else{break;}}while (true){std::cout << "Please enter the time slot for requesting an appointment:" << std::endl;std::cout << "1, Morning 8:00-12:00" << std::endl;std::cout << "2, Afternoon 13:00-17:00" << std::endl;std::cout << "3, Evening 18:00-22:00" << std::endl;std::cin >> time_slot;if (time_slot < 1 || time_slot>3){std::cout << "Time slot is invalid input!" << std::endl;std::cout << "-------------------" << std::endl;}else{break;}}while (true) {std::cout << "Please select a laboratory:" << std::endl;for (int i = 0; i < this->v_Lab.size(); i++){std::cout << i + 1 << ". " << this->v_Lab[i].get_lab_name() << " (Capacity: " << this->v_Lab[i].get_lab_max_capacity() << ")" << std::endl;}std::cin >> lab_id;if (lab_id < 1 || lab_id>this->v_Lab.size()){std::cout << "Laboratory id is invalid input!" << std::endl;std::cout<<"-------------------"<<std::endl;}else{break;}}std::cout<<"The appointment application is successful! Wait for the lab teacher to review it."<<std::endl;std::ofstream ofs;//写入预约信息ofs.open(ORDER_FILE, std::ios::app);if (!ofs.is_open()){std::cout << "Error: can not open file " << ORDER_FILE << std::endl;return;}ofs << "day:" << day << " ";ofs<<"time_slot:" << time_slot << " " ;ofs<<"student_id:" << this->getId() << " " ;ofs<<"student_name:"<<this->getName()<<" " ;ofs<<"lab_id:"<<lab_id<<" " ;ofs<<"lab_name:"<<this->v_Lab[lab_id-1].get_lab_name()<<" " ;ofs<<"status:"<<1<<std::endl;//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消ofs.close();system("pause");system("cls");
}void Student::showMyOrder() //显示我的预约
{int number{0};//实验室申请记录条数LabAppointments appointments;//预约信息if (appointments.getAppointments() == 0)//如果没有预约信息{std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}for (int i = 0; i < appointments.getAppointments(); i++) {//this->getId()                                                   是一个int类型//appointments.v_Appointments[i]["student_id"]                    是一个string类型//appointments.v_Appointments[i]["student_id"].c_str()            是一个char*类型,是C语言的字符串;.c_str()将string 转 const char*//atoi(appointments.v_Appointments[i]["student_id"].c_str())      是一个int类型,是C语言的整数;      atoi()将const char* 转 int//所以可以比较两个string类型的值if (std::atoi(appointments.v_Appointments[i]["student_id"].c_str()) == this->getId())//如果是自己的预约{number++;std::cout << "Your appointment is the day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1"?"Morning":(appointments.v_Appointments[i]["time_slot"] == "2")?"Afternoon":(appointments.v_Appointments[i]["time_slot"] == "3")?"Evening":"Your Appointment Time Slot Is Error.");std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; statis: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1"){status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2"){status += "Approved";}else if (appointments.v_Appointments[i]["status"] == "3"){status += "Rejected";}else if (appointments.v_Appointments[i]["status"] == "4"){status += "Canceled";}else{status += "Your Appointment Status Is Error.";}std::cout << " " << status << std::endl;}}std::cout << "Total " << number << " LabAppointments Appointment!" << std::endl;system("pause");system("cls");
}void Student::showAllOrder() //显示所有预约
{LabAppointments appointments;if (appointments.getAppointments() == 0){std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}for (int i = 0; i < appointments.getAppointments(); i++){std::cout << i + 1 << ".";std::cout << "The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1"?"Morning":(appointments.v_Appointments[i]["time_slot"] == "2")?"Afternoon":(appointments.v_Appointments[i]["time_slot"] == "3")?"Evening":"Your Appointment Time Slot Is Error.");std::cout << "; student_id is: " << appointments.v_Appointments[i]["student_id"];std::cout << "; student_name is: " << appointments.v_Appointments[i]["student_name"];std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; statis: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1"){status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2"){status += "Approved";}else if (appointments.v_Appointments[i]["status"] == "3"){status += "Rejected";}else if (appointments.v_Appointments[i]["status"] == "4"){status += "Canceled";}else{status += "Your Appointment Status Is Error.";}std::cout << " " << status << std::endl;}system("pause");system("cls");
}void Student::cancelOrder() //取消预约
{LabAppointments appointments;if (appointments.getAppointments() == 0) {std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}std::cout << "Records that are under review or have a successful appointment can be canceled, so please enter the canceled record:" << std::endl;std::vector<int> v_index;int index = 1;for (int i = 0; i < appointments.getAppointments(); i++){if (atoi(appointments.v_Appointments[i]["student_id"].c_str()) == this->getId())//是自己的预约{if (appointments.v_Appointments[i]["status"] == "1" || appointments.v_Appointments[i]["status"] == "2")//审核中或已通过的预约可以取消{v_index.push_back(i);std::cout << index << ". ";std::cout <<" The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1"?"Morning":(appointments.v_Appointments[i]["time_slot"] == "2")?"Afternoon":(appointments.v_Appointments[i]["time_slot"] == "3")?"Evening":"Your Appointment Time Slot Is Error.");std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; statis: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1")//审核中{status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2")//已通过{status += "Approved";}std::cout << " " << status << std::endl;index++;}}}std::cout << "Please enter the index of the canceled record, or enter 0 to return:" << std::endl;int select = 0;while (true){std::cin >> select;if (select >= 0 && select <= v_index.size()){if (select == 0) //输入0表示取消{break;}else {int i = v_index[select - 1];appointments.v_Appointments[i]["status"] = "4";//将状态设置为已取消appointments.updateAppointments();std::cout << "The appointment has been canceled successfully!" << std::endl;break;}}std::cout << "You have made a mistake, please re-enter." << std::endl;}system("pause");system("cls");
}

10,Teacher.h

#pragma once
#include "Identify.h"
#include "LabAppointments.h"
#include <vector>class Teacher:public Identify
{
public:Teacher();Teacher(int teacher_id,std::string name,std::string pwd);virtual void Identify::selectMenu() override;//功能菜单实现void showAllOrder();//显示所有预约void validOrder();//审核预约int getId() {return this->teacher_id_;}void setId(int id) {this->teacher_id_ = id;}private:int teacher_id_;//教职工编号
};

11,Teacher.cpp

#include "Teacher.h"
Teacher::Teacher() {}Teacher::Teacher(int teacher_id,std::string name,std::string pwd) 
{//初始化实验室教师职工号、姓名、密码this->setId(teacher_id);this->setName(name);this->setPwd(pwd);
}void Teacher::selectMenu() //功能菜单实现
{std::cout << "Weclome teacher: " << this->getName() << "login!" << std::endl;std::cout << "\t\t ---------------------------------\n";std::cout << "\t\t|          1.showAllOrder         |\n";std::cout << "\t\t|          2.validOrder           |\n";std::cout << "\t\t|          0 or OtherKey.logout   |\n";std::cout << "\t\t ---------------------------------\n";std::cout << "Please select your action: " << std::endl;
}void Teacher::showAllOrder()//显示所有预约
{LabAppointments appointments;if (appointments.getAppointments() == 0){std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}for (int i = 0; i < appointments.getAppointments(); i++){std::cout << i + 1 << ".";std::cout << "The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1" ? "Morning" : (appointments.v_Appointments[i]["time_slot"] == "2") ? "Afternoon" : (appointments.v_Appointments[i]["time_slot"] == "3") ? "Evening" : "Your Appointment Time Slot Is Error.");std::cout << "; student_id is: " << appointments.v_Appointments[i]["student_id"];std::cout << "; student_name is: " << appointments.v_Appointments[i]["student_name"];std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; status: ";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消if (appointments.v_Appointments[i]["status"] == "1"){status += "Pending Review";}else if (appointments.v_Appointments[i]["status"] == "2"){status += "Approved";}else if (appointments.v_Appointments[i]["status"] == "3"){status += "Rejected";}else if (appointments.v_Appointments[i]["status"] == "4"){status += "Canceled";}else{status += "Your Appointment Status Is Error.";}std::cout << " " << status << std::endl;}system("pause");system("cls");
}void Teacher::validOrder() //审核预约
{LabAppointments appointments;if (appointments.getAppointments() == 0){std::cout << "No LabAppointments Appointment!" << std::endl;system("pause");system("cls");return;}std::cout << "The records of laboratory appointments to be reviewed are as follows:" << std::endl;std::vector<int> v_valid_order;int index = 1;for (int i = 0; i < appointments.getAppointments(); i++){if (appointments.v_Appointments[i]["status"] == "1")//1表示审核中{v_valid_order.push_back(i);std::cout << index++ << ".";std::cout << "The day: " << appointments.v_Appointments[i]["day"];std::cout << "; time slot is: " << (appointments.v_Appointments[i]["time_slot"] == "1" ? "Morning" : (appointments.v_Appointments[i]["time_slot"] == "2") ? "Afternoon" : (appointments.v_Appointments[i]["time_slot"] == "3") ? "Evening" : "Your Appointment Time Slot Is Error.");std::cout << "; student_id is: " << appointments.v_Appointments[i]["student_id"];std::cout << "; student_name is: " << appointments.v_Appointments[i]["student_name"];std::cout << "; lab_id is: " << appointments.v_Appointments[i]["lab_id"];std::cout << "; lab_name is: " << appointments.v_Appointments[i]["lab_name"];std::string status = "; status: Pending Revie";//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消std::cout << status << std::endl;}}//输入审核的实验室预约序号,0表示返回,不想审核了std::cout << "Please enter the lab appointment record you want to review, 0 means return" << std::endl;int select = 0;//实验室教师选择要审核的预约序号int ret = 0;//接收实验室教师给的审核结果,1表示审核通过,2表示审核拒绝while (true){std::cin >> select;if (select >= 0 && select <= v_valid_order.size()){if (select == 0)//选择0,表示不想审核了,退出循环即可{break;}else{//1表示审核中,2表示已通过,3表示已拒绝,4表示已取消std::cout << "Please enter the result of the review" << std::endl;std::cout << "1. Approved" << std::endl;std::cout << "2. Rejected" << std::endl;std::cin >> ret;if (ret == 1){appointments.v_Appointments[v_valid_order[select - 1]]["status"] = "2";}else if (ret == 2){appointments.v_Appointments[v_valid_order[select - 1]]["status"] = "3";}else{std::cout << "Your input is error!" << std::endl;continue;}appointments.updateAppointments();//更新预约信息到文件中std::cout << "The review result has been saved!" << std::endl;break;}}std::cout << "You have made a mistake, please re-enter." << std::endl;}system("pause");system("cls");
}

12,main.cpp

#include <iostream>
#include "Identify.h"
#include <fstream>
#include "globalFile.h"
#include "Student.h"
#include "Teacher.h"
#include "Admin.h"//管理员身份菜单界面
void AdminMenu(Identify*& identify_p) //传入父类的指针
{//进入菜单界面while (true) {//调用管理员子菜单identify_p->selectMenu();//这是父类指针,只能调用公共的接口纯虚函数//想要调用子类特有的接口,需要把父类指针转回去,将父类的指针转为子类的指针Admin* admin = (Admin*)identify_p;int userselect = 0;//用户的选择std::cin >> userselect;//接收用户的选择if (userselect == 1) //添加账号{//std::cout << "Your select is add an account" << std::endl;admin->addUser();}else if (userselect == 2)//查看账号{//std::cout << "Your select is view all account" << std::endl;admin->showUser();}else if (userselect == 3) //添加实验室信息{//std::cout << "Your select is add lab information" << std::endl;admin->addLabInfo();}else if (userselect == 4) //显示实验室信息{//std::cout << "Your select is show lab information" << std::endl;admin->showLabInfo();}else if (userselect == 5) //清空预约{//std::cout << "Your select is clear all appointment" << std::endl;admin->cleanRecord();}else//选成其他选项,默认代表注销登录{delete admin;//销毁堆区创建的对象std::cout << "The logout is successful" << std::endl;system("pause");system("cls");return;}}
}//学生身份菜单界面
void StudentMenu(Identify*& identify_p) //传入父类的指针
{//进入菜单界面while(true){//调用管理员子菜单identify_p->selectMenu();//这是父类指针,只能调用公共的接口纯虚函数//想要调用子类特有的接口,需要把父类指针转回去,将父类的指针转为子类的指针Student* student = (Student*)identify_p;int userselect = 0;//用户的选择std::cin >> userselect;//接收用户的选择if (userselect == 1) //申请实验室预约{//std::cout << "Your select is apply for lab appointment" << std::endl;student->applyOrder();}else if (userselect == 2) //查看自身预约信息{//std::cout << "Your select is view your appointment information" << std::endl;student->showMyOrder();}else if (userselect == 3) //查看所有的实验室预约信息{//std::cout << "Your select is view all appointment information" << std::endl;student->showAllOrder();}else if (userselect == 4) //取消实验室预约{//std::cout << "Your select is cancel lab appointment" << std::endl;student->cancelOrder();}else //选成其他选项,默认代表注销登录{delete student;//销毁堆区创建的对象std::cout << "The logout is successful" << std::endl;system("pause");system("cls");return;}}
}//实验室教师身份菜单页面
void TeacherMenu(Identify*& identify_p) //传入父类的指针
{//进入菜单界面while (true){//调用管理员子菜单identify_p->selectMenu(); //这是父类指针,只能调用公共的接口纯虚函数Teacher* teacher = (Teacher*)identify_p; //将父类指针转为子类指针int userselect = 0; //用户的选择std::cin >> userselect; //接收用户的选择if (userselect == 1) {//std::cout << "Your select is view all appointment information" << std::endl;teacher->showAllOrder();}else if (userselect == 2){//std::cout << "Your select is valid appointment information" << std::endl;teacher->validOrder();}else//选成其他选项,默认代表注销登录{delete teacher; //销毁堆区创建的对象std::cout << "The logout is successful" << std::endl;system("pause");system("cls");return;}}
}//全局登录函数
//参数一:操作的文件名称
//参数二:身份(1为学生、2为实验室教师、3为管理员)
void Login(std::string fileName,int type) 
{//创建父类指针,将来通过多态指向子类对象Identify* identify_p = NULL;//读取文件std::ifstream ifs;ifs.open(fileName, std::ios::in);//以读的方式打开文件//若文件不存在if (!ifs.is_open()) //打开失败{std::cout << "The file does not exist" << std::endl;ifs.close();return;}//存放用户将来输入的信息int id = 0;//存储学号或职工号std::string name;//学生或实验室教师的姓名std::string pwd;//学生或实验室教师的密码if (type == 1) {std::cout << "Please input your student_id:" << std::endl;std::cin >> id;}else if (type == 2) {std::cout << "Please input your teacher_id:" << std::endl;std::cin >> id;}std::cout << "Please input your name:" << std::endl;std::cin >> name;std::cout << "Please input your password:" << std::endl;std::cin >> pwd;if (type == 1){//student loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd) //学号、姓名、密码均输入成功{std::cout << "Student verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Student(id, name, pwd);//父类指针指向子类对象,创建学生实例//进入学生身份的子菜单StudentMenu(identify_p);return;}}}else if (type == 2) {//teacher loginint f_id;//文件读取得到的idstd::string f_name;//从文件中获取得到的namestd::string f_pwd; //从文件中获取得到的pwdwhile (ifs >> f_id && ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_id == id && f_name == name && f_pwd == pwd)//教职工编号、姓名、密码输入成功 {std::cout << "Teacher verification login is successful!" << std::endl;system("pause");system("cls");identify_p = new Teacher(id, name, pwd);//父类指针指向子类对象,创建教职工实例//进入实验室教师身份的子菜单TeacherMenu(identify_p);return;}}}else if (type == 3) {//admin loginstd::string f_name;//从文件中获取得到的namestd::string f_pwd;//从文件中获取得到的pwdwhile (ifs >> f_name && ifs >> f_pwd) //文件按行读取,遇到空格存一下,每行数据信息拆成三个{//文件读取得到的信息与用户输入的信息进行对比if (f_name == name && f_pwd == pwd) //管理员登录只需要姓名和密码 {std::cout << "Admin verification login is successful!" << std::endl;system("pause");system("cls");	identify_p = new Admin(name, pwd);//父类指针指向子类对象,创建管理员实例//进入管理员身份的子菜单AdminMenu(identify_p);return;}}}std::cout << "Validation failed !" << std::endl;system("pause");system("cls");return;
}int main() {int select = 0;//存放用户的选择while (true){std::cout << "======================  Welcome to the Laboratory Management System  =====================" << std::endl;std::cout << "\t\t -------------------------------\n";std::cout << "\t\t|          1.Student            |\n";std::cout << "\t\t|          2.Teacher            |\n";std::cout << "\t\t|          3.Admin              |\n";std::cout << "\t\t|          0.Exit               |\n";std::cout << "\t\t -------------------------------\n";std::cout << std::endl << "Please enter your identity: " << std::endl;std::cin >> select; //接受用户选择switch (select){case 1:  //学生身份Login(STUDENT_FILE,1);break;case 2:  //老师身份Login(TEACHER_FILE, 2);break;case 3:  //管理员身份Login(ADMIN_FILE, 3);break;case 0:  //退出系统std::cout << "Welcome to you next time!" << std::endl;system("pause");return 0;break;default:std::cout << "You have entered the wrong information, please make a new selection!" << std::endl;system("pause");system("cls");break;}}system("pause");return 0;
}

五、项目下载链接

实验室预约综合管理系统

这篇关于STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150145

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。