C++系列内容的学习目录 → \rightarrow →C++学习系列内容汇总。
本案例由于内容较多,故分为四个篇章。
1-6部分的内容见 C++ 综合大案例 :机房预约系统(1)
7部分的内容见 C++ 综合大案例 :机房预约系统(2)
8-9部分的内容见 C++ 综合大案例 :机房预约系统(3)
10部分的内容见 C++ 综合大案例 :机房预约系统(4)
1. 机房预约系统需求
1.1 系统简介
学校现有几个规格不同的机房,由于使用时经常出现"撞车"现象,现开发一套机房预约系统,解决这一问题。
1.2 身份简介
分别有三种身份使用该程序:
- 学生代表:申请使用机房;
- 老师:审核学生的预约申请;
- 管理员:给学生、老师创建账号。
1.3 机房简介
机房总共有3间:
- 1号机房:最大容量20人;
- 2号机房:最多容量50人;
- 3号机房:最多容量100人。
1.4 申请简介
- 申请的订单每周由管理员负责清空;
- 学生可以预约未来一周内的机房使用,预约的日期为周一至周五,预约时需要选择预约时段(上午、下午);
- 老师来审核预约,依据实际情况审核预约通过或者不通过。
1.5 系统具体需求
- 首先进入登录界面,可选登录身份有:
⋄ \diamond ⋄ 学生代表
⋄ \diamond ⋄ 老师
⋄ \diamond ⋄ 管理员
⋄ \diamond ⋄ 退出 - 每个身份都需要进行验证后,进入子菜单:
⋄ \diamond ⋄ 学生需要输入 :学号、姓名、登录密码
⋄ \diamond ⋄ 老师需要输入:职工号、姓名、登录密码
⋄ \diamond ⋄ 管理员需要输入:管理员姓名、登录密码 - 学生具体功能:
⋄ \diamond ⋄ 申请预约:预约机房
⋄ \diamond ⋄ 查看自身的预约:查看自己的预约状态
⋄ \diamond ⋄ 查看所有预约:查看全部预约信息以及预约状态
⋄ \diamond ⋄ 取消预约:取消自身的预约,预约成功或审核中的预约均可取消
⋄ \diamond ⋄ 注销登录:退出登录 - 老师具体功能:
⋄ \diamond ⋄ 查看所有预约:查看全部预约信息以及预约状态
⋄ \diamond ⋄ 审核预约:对学生的预约进行审核
⋄ \diamond ⋄ 注销登录:退出登录 - 管理员具体功能:
⋄ \diamond ⋄ 添加账号:添加学生或老师的账号,需要检测学生编号或教师职工号是否重复
⋄ \diamond ⋄ 查看账号:可以选择查看学生或老师的全部信息
⋄ \diamond ⋄ 查看机房:查看所有机房的信息
⋄ \diamond ⋄ 清空预约:清空所有预约记录
⋄ \diamond ⋄ 注销登录:退出登录
2. 创建项目
创建项目的步骤: 1. 创建新项目机房预约系统
;
2. 添加文件机房预约系统.cpp
。
具体步骤参见C++基础入门(一)—— C++初识中的第三小节内容。
3. 创建主菜单
功能描述: 设计主菜单,与用户进行交互。
3.1 菜单实现
在主函数main中添加菜单提示,代码如下所示。
#include<iostream>
using namespace std;
int main()
{
cout << "===================== 欢迎来到机房预约系统 ====================" << endl;
cout << endl << "请选择您的身份" << 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| 0.退 出 |\n";
cout << "\t\t| |\n";
cout << "\t\t -------------------------------\n";
cout << "输入您的选择:";
system("pause");
return 0;
}
运行效果如图如下所示。
3.2 搭建接口
接受用户的选择,搭建接口,在main中添加如下所示的代码。
int main()
{
int select = 0; //用于接收用户的选择
while (true)
{
cout << "===================== 欢迎来到机房预约系统 ====================" << endl;
cout << endl << "请选择您的身份" << 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| 0.退 出 |\n";
cout << "\t\t| |\n";
cout << "\t\t -------------------------------\n";
cout << "输入您的选择:";
cin >> select; //接收用户选择
switch (select) //根据用户不同选择,实现不同接口
{
case 1: //学生身份
break;
case 2: //老师身份
break;
case 3: //管理员身份
break;
case 0: //退出系统
break;
default:
cout << "输入有误,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
system("pause");
return 0;
}
- 测试:输入0、1、2、3会重新回到界面,效果如下图所示。
- 测试:输入除0、1、2、3之外的其他选项,提示输入有误,清屏后重新选择,效果如下图所示。
至此,界面搭建完毕!
4. 退出功能实现
4.1 退出功能实现
在main函数的switch case语句中case 0:
里添加退出程序的代码,如下所示。
case 0: //退出系统
cout << "欢迎下一次使用!" << endl;
system("pause");
return 0;
break;
4.2 测试退出功能
运行程序,测试效果图如下所示。
至此,退出程序功能实现!
5. 创建身份类
5.1 身份的基类
- 在整个系统中,有三种身份,分别为:学生代表、老师以及管理员;
- 三种身份有其共性也有其特性,因此我们可以将三种身份抽象出一个身份基类Identity;
- 在头文件下创建
Identity.h
文件。
在Identity.h
中添加如下所示的代码。
#pragma once
#include<iostream>
using namespace std;
//身份抽象基类
class Identity
{
public:
//操作菜单(纯虚函数)
virtual void operMenu() = 0;
string m_Name; //用户名
string m_Pwd; //密码
};
5.2 学生类
5.2.1 功能分析
-
学生类的主要功能是可以通过类中成员函数,实现预约机房的操作。
-
学生类中主要功能有:
⋄ \diamond ⋄ 显示学生操作的菜单界面
⋄ \diamond ⋄ 申请预约
⋄ \diamond ⋄ 查看自身预约
⋄ \diamond ⋄ 查看所有预约
⋄ \diamond ⋄ 取消预约
5.2.2 类的创建
在头文件以及源文件下创建student.h
和student.cpp
文件。
student.h
中添加如下所示的代码。
#pragma once
#include<iostream>
using namespace std;
#include"Identity.h"
//学生类
class Student :public Identity
{
public:
//默认构造
Student();
//有参构造(参数:学号、姓名、密码)
Student(int id,string name,string pwd);
//菜单界面
virtual void operMenu();
//申请预约
void applyOrder();
//查看自身预约
void showMyOrder();
//查看所有预约
void showAllOrder();
//取消预约
void cancelOrder();
//学生学号
int m_Id;
};
student.cpp
中添加如下所示的代码。
#include"student.h"
//默认构造
Student::Student()
{
}
//有参构造(参数:学号、姓名、密码)
Student::Student(int id, string name, string pwd)
{
}
//菜单界面
void Student::operMenu()
{
}
//申请预约
void Student::applyOrder()
{
}
//查看自身预约
void Student::showMyOrder()
{
}
//查看所有预约
void Student::showAllOrder()
{
}
//取消预约
void Student::cancelOrder()
{
}
5.3 老师类
5.3.1 功能分析
-
教师类的主要功能是查看学生的预约,并进行审核。
-
教师类中主要功能有:
⋄ \diamond ⋄ 显示教师操作的菜单界面
⋄ \diamond ⋄ 查看所有预约
⋄ \diamond ⋄ 审核预约
5.3.2 类的创建
在头文件以及源文件下创建teacher.h
和teacher.cpp
文件。
teacher.h
中添加如下所示的代码。
#pragma once
#include<iostream>
using namespace std;
#include"Identity.h"
//教师类
class Teacher :public Identity
{
public:
//默认构造函数
Teacher();
//有参构造函数(参数:职工号、姓名、密码)
Teacher(int empId, string name, string pwd);
//菜单界面
virtual void operMenu();
//查看所有预约
void showAllOrder();
//审核预约
void valiOrder();
//职工号
int m_EmpId;
};
teacher.cpp
中添加如下所示的代码。
#include"teacher.h"
//默认构造函数
Teacher::Teacher()
{
}
//有参构造函数(参数:职工号、姓名、密码)
Teacher::Teacher(int empId, string name, string pwd)
{
}
//菜单界面
void Teacher::operMenu()
{
}
//查看所有预约
void Teacher::showAllOrder()
{
}
//审核预约
void Teacher::valiOrder()
{
}
5.4 管理员类
5.4.1 功能分析
-
管理员类的主要功能是对学生和老师账号进行管理,查看机房信息以及清空预约记录。
-
管理员类中主要功能有:
⋄ \diamond ⋄ 显示管理员操作的菜单界面
⋄ \diamond ⋄ 添加账号
⋄ \diamond ⋄ 查看账号
⋄ \diamond ⋄ 查看机房信息
⋄ \diamond ⋄ 清空预约记录
5.4.2 类的创建
在头文件以及源文件下创建manager.h
和manager.cpp
文件。
manager.h
中添加如下所示的代码。
#pragma once
#include<iostream>
using namespace std;
#include"Identity.h"
//管理员类
class Manager :public Identity
{
public:
//默认构造
Manager();
//有参构造函数(参数:姓名、密码)
Manager(string name, string pwd);
//菜单界面
virtual void operMenu();
//添加账号
void addPerson();
//查看账号
void showPerson();
//查看机房信息
void showComputer();
//清空预约记录
void cleanFile();
};
manager.cpp
中添加如下所示的代码。
#include"manager.h"
//默认构造
Manager::Manager()
{
}
//有参构造函数(参数:姓名、密码)
Manager::Manager(string name, string pwd)
{
}
//菜单界面
void Manager::operMenu()
{
}
//添加账号
void Manager::addPerson()
{
}
//查看账号
void Manager::showPerson()
{
}
//查看机房信息
void Manager::showComputer()
{
}
//清空预约记录
void Manager::cleanFile()
{
}
至此,所有身份类创建完毕,效果如下图所示。
6. 登录模块
6.1 全局文件添加
功能描述: 不同的身份可能会用到不同的文件操作,我们可以将所有的文件名定义到一个全局的文件中。
在头文件中添加globalFile.h
文件,并添加如下所示的代码。
#pragma once
//管理员文件
#define ADMIN_FILE "admin.txt"
//学生文件
#define STUDENT_FILE "student.txt"
//老师文件
#define TEACHER_FILE "teacher.txt"
//机房信息文件
#define COMPUTER_FILE "computerRoom.txt"
//订单文件
#define ORDER_FILE "order.txt"
在同级目录下,创建文件admin.txt
、computerRoom.txt
、order.txt
、student.txt
、teacher.txt
。
6.2 登录函数封装
功能描述: 根据用户的选择,进入不同的身份登录。
在机房预约系统.cpp
文件中添加全局函数 void LoginIn(string fileName, int type)
,代码如下所示。
参数: fileName — 操作的文件名;
type — 登录的身份 (1代表学生、2代表老师、3代表管理员)。
//登录功能(参数1:操作文件名;参数2:操作身份类型)
void LoginIn(string fileName, int type)
{
//父类指针,用于指向子类对象
Identity * person = NULL;
//读文件
ifstream ifs;
ifs.open(fileName, ios::in);
//判断文件是否存在
if (!ifs.is_open())
{
cout << "文件不存在!" << endl;
ifs.close();
return;
}
//准备接收用户的信息
int id = 0;
string name;
string pwd;
//判断身份
if (type == 1) //学生身份
{
cout << "请输入学号:" << endl;
cin >> id;
}
else if (type == 2) //老师身份
{
cout << "请输入职工号:" << endl;
cin >> id;
}
cout << "请输入用户名:" << endl;
cin >> name;
cout << "请输入密码:" << endl;
cin >> pwd;
if (type == 1)
{
//学生身份验证
}
else if (type == 2)
{
//老师身份验证
}
else if (type == 3)
{
//管理员身份验证
}
cout << "身份验证登录失败!" << endl;
system("pause");
system("cls");
}
在main函数的switch case语句中case 1:
、case 2:
、case 3:
里分布添加不同的登录接口,代码如下所示。
case 1: //学生身份
LoginIn(STUDENT_FILE, 1);
break;
case 2: //老师身份
LoginIn(TEACHER_FILE, 2);
break;
case 3: //管理员身份
LoginIn(ADMIN_FILE, 3);
break;
6.3 学生登录实现
在 student.txt 文件中添加两条学生信息用于测试,添加信息如下所示。
1 张三 123
2 李四 123456
其中,第一列代表学号;第二列代表学生姓名;第三列代表密码。
添加后的效果图如下图所示。
在LoginIn()
函数的学生分支中添加如下所示的代码,验证学生身份。
//学生身份验证
int fId; //从文件中获取id号
string fName; //从文件中获取姓名
string fPwd; //从文件中获取密码
while (ifs >> fId && ifs >> fName && ifs >> fPwd) //因为txt文件中加了空格,所以可以依次读取
{
//与用户输入的信息做对比
if (fId == id && fName == name && fPwd == pwd)
{
cout << "学生身份验证登录成功!" << endl;
system("pause");
system("cls");
person = new Student(id, name, pwd); //在堆区创建学生
//进入学生身份的子菜单
return;
}
}
运行代码读取txt文件内容的过程中,可能会出现乱码的问题,解决方法见 → \rightarrow →解决C++中读取txt文件内容时出现乱码的问题。
测试效果如下图所示。
- 测试:学生身份验证成功
- 测试:学生身份验证失败
6.4 教师登录实现
在teacher.txt文件中添加一条老师信息用于测试,添加信息如下所示。
1 老王 123
其中,第一列代表教师职工编号;第二列代表教师姓名;第三列代表密码。
添加后的效果图如下图所示。
在LoginIn()
函数的老师分支中添加如下所示的代码,验证老师身份。
//老师身份验证
int fId; //从文件中获取的id号
string fName; //从文件中获取姓名
string fPwd; //从文件中获取密码
while (ifs >> fId && ifs >> fName && ifs >> fPwd)
{
if (fId == id && fName == name && fPwd == pwd)
{
cout << "老师身份验证登录成功!" << endl;
system("pause");
system("cls");
person = new Teacher(id, name, pwd); //在堆区创建老师
//进入老师身份的子菜单
return;
}
}
测试效果如下图所示。
- 测试:老师身份验证成功
- 测试:老师身份验证失败
6.5 管理员登录实现
在 admin.txt 文件中添加一条管理员信息,由于我们只有一个管理员,因此本案例中没有添加管理员的功能。所添加的管理员信息如下所示。
admin 123
其中,第一列代表管理员用户名;第二列代表密码。
添加后的效果图如下图所示。
在LoginIn()
函数的管理员分支中添加如下所示的代码,验证管理员身份。
//管理员身份验证
string fName; //从文件中获取姓名
string fPwd; //从文件中获取密码
while (ifs >> fName && ifs >> fPwd)
{
if (name == fName && pwd == fPwd)
{
cout << "管理员身份验证登录成功!" << endl;
system("pause");
system("cls");
person = new Manager(name, pwd); //在堆区创建老师
//进入管理员身份的子菜单
return;
}
}
测试效果如下图所示。
- 测试:管理员身份验证成功
- 测试:管理员身份验证失败
至此,所有身份的登录功能全部实现!
7. 管理员模块
7部分的内容见C++ 综合大案例 :机房预约系统(2)。
8. 学生模块
9. 老师模块
8-9部分的内容见C++ 综合大案例 :机房预约系统(3)。
10. 附录:完整代码
10部分的内容见C++ 综合大案例 :机房预约系统(4)。