实现步骤:
void Student::operMenu()
,显示学生子菜单界面void studentMenu(Identity * &manager)
Student.cpp 初始化学生属性 代码展示:
//有参构造(学号、姓名、密码)
Student::Student(int id, string name, string pwd)
{
//初始化属性
this->m_Id = id;
this->m_Name = name;
this->m_Pwd = pwd;
}
//菜单界面
void Student::operMenu()
{
cout << "欢迎学生代表:" << this->m_Name << "登录!" << endl;
cout << "\t\t ----------------------------------\n";
cout << "\t\t| |\n";
cout << "\t\t| 1.申请预约 |\n";
cout << "\t\t| |\n";
cout << "\t\t| 2.查看我的预约 |\n";
cout << "\t\t| |\n";
cout << "\t\t| 3.查看所有预约 |\n";
cout << "\t\t| |\n";
cout << "\t\t| 4.取消预约 |\n";
cout << "\t\t| |\n";
cout << "\t\t| 0.注销登录 |\n";
cout << "\t\t| |\n";
cout << "\t\t ----------------------------------\n";
cout << "请选择您的操作: " << endl;
}
机房预约系统.cpp studentMenu函数 学生子菜单框架 代码展示:
这部分和管理员的子菜单类似,不赘诉
//全局函数 进入学生子菜单界面
void studentMenu(Identity*& student)
{
while (1)
{
//调用子菜单
student->openMenu();
//将父类指针转为子类指针,调用子类的其他接口
Student* stu = (Student*)student;
//接收用户选择功能
int select = 0;
cin >> select;
switch (select)
{
case 1://申请预约
cout << "申请预约" << endl;
stu->applyOrder();
break;
case 2://查看自身预约
cout << "查看自身预约" << endl;
stu->showmyOrder();
break;
case 3://查看所有预约
cout << "查看所有预约" << endl;
stu->showallOrder();
break;
case 4://取消预约
cout << "取消预约" << endl;
stu->cancleOrder();
break;
default://默认情况下注销登录 释放堆区数据
delete stu;//释放堆区数据 手动开辟手动释放
cout << "注销成功!" << endl;
system("pause");
system("cls");
return;
}
}
}
机房预约系统.cpp LoginIn函数 接口对接 代码位置:
实现步骤:
vector vCom;
Student.h
//机房容器
vector vCom;
Student.cpp 有参构造函数 代码展示
//有参构造(学号、姓名、密码)
Student::Student(int id, string name, string password)
{
this->m_Id = id;
this->m_Name = name;
this->m_Password = password;
//初始化机房信息 读取信息
ifstream ifs;
ifs.open(COMPUTER_FILE, ios::in);
ComputerRoom com;
while (ifs >> com.m_ComId && ifs >> com.m_MaxNum)
{
vCom.push_back(com);//读到的信息存在vector容器中
}
ifs.close();
}
实现步骤:
void Student::applyOrder()
,这部分分为预约信息输入和预约信息写入。student.cpp 申请预约 代码展示:
//申请预约
void Student::applyOrder()
{
int n = 15;
int data = 0;//接收预约日期变量
cout << string(n, '*') << " 机房开放时间为周一至周五! " << string(n, '*') << endl;
cout << string(n, ' ') << " 请输入申请预约的时间: " << string(n, ' ') << endl;
cout << string(n, ' ') << " 1—— 周一 " << string(n, ' ') << endl;
cout << string(n, ' ') << " 2—— 周二 " << string(n, ' ') << endl;
cout << string(n, ' ') << " 3—— 周三 " << string(n, ' ') << endl;
cout << string(n, ' ') << " 4—— 周四 " << string(n, ' ') << endl;
cout << string(n, ' ') << " 5—— 周五 " << string(n, ' ') << endl;
//cout << "请输入申请预约的时间:" << endl;
//cout << "1—— 周一" << endl;
//cout << "2—— 周二" << endl;
//cout << "3—— 周三" << endl;
//cout << "4—— 周四" << endl;
//cout << "5—— 周五" << endl;1
//预约日期输入判断
while (true)
{
cin >> data;
if (1 <= data <= 5)//输入正确
{
break;
}
cout << "输入有误,请重新输入!" << endl;
}
int period = 0;//接收预约时间段变量
cout << string(n, '-') << " 请输入申请预约的时间段: " << string(n, '-') << endl;
cout << string(16, ' ') << "1—— 上午" << string(n, ' ') << endl;
cout << string(16, ' ') << "2—— 下午" << string(n, ' ') << endl;
while (true)
{
cin >> period;
if (period == 1 || period == 2)
{
break;
}
cout << "输入有误,请重新输入!" << endl;
}
int room = 0;//接收预约机房编号变量
cout << string(n, '-') << " 请输入申请预约的机房: " << string(n, '-') << endl;
for (vector::iterator it = vCom.begin(); it != vCom.end(); it++)
{
cout << string(16, ' ') << "机房编号为:" << it->m_ComId << "\t机房容量为:" << it->m_MaxNum << endl;
}
/*for (int i = 0; i < vCom.size(); i++)
{
cout << "机房编号为:" << vCom[i].m_ComId << "\t机房容量为:" << vCom[i].m_MaxNum << endl;
}*/
while (true)
{
cin >> room;
if (1 <= room <= 3)
{
break;
}
cout << "输入有误,请重新输入!" << endl;
}
cout << string(n, '*') << " 预约成功,审核中! " << string(n, '*') << endl;
//预约信息写入
ofstream ofs;
ofs.open(ORDER_FILE, ios::app);
ofs << "data:" << data << " ";
ofs << "period:" << period << " ";
ofs << "stuID:" << this->m_Id << " ";
ofs << "stuName:" << this->m_Name << " ";
ofs << "roomID:" << room << " ";
ofs << "status:" << 1 << " " << endl;
ofs.close();
system("pause");
system("cls");
}
测试效果:
在order.txt文件中生成如下内容:
功能描述: 显示预约记录时,需要从order.txt文件中获取到所有预约记录并显示。因此,创建预约类来管理预约记录以及更新预约的状态。
实现过程与代码:
#include "orderFile.h"
map m;
,以及临时接受key和value值的string变量。虽然除了姓名是字符串,其他信息都是数字,但是为了方便,统一用string类型来接收key和value。stuName.size()
,stuName: 的长度可以用pos表示,那么Bella的长度是stuName.size() - pos - 1
。pair subdata(string data);
,在orderFile.cpp写实现,并测试。要注意函数的类型是pair subdata(string data);
,因为截取完后,key和value都要存入小容器m中。orderFile.h 完整代码展示
#pragma once
#include
using namespace std;
using std::pair;
#include
OrderFile.cpp 构造函数 截取函数 完整代码展示
#include "orderFile.h"
//构造函数
orderFile::orderFile()
{
ifstream ifs(ORDER_FILE, ios::in);
//接收预约文件各信息变量
string date;
string period;
string stuID;
string stuName;
string roomID;
string status;
this->m_Size = 0;//初始化为0
while ( ifs >> date && ifs >> period && ifs >> stuID
&& ifs >> stuName && ifs >> roomID && ifs >> status)
{
//测试
/*cout << data << endl;
cout << period << endl;
cout << stuID << endl;
cout << stuName << endl;
cout << roomID << endl;
cout << status << endl;*/
map<string, string> m;
//截取日期
/*
//截取key value值并存入map小容器中 统一用string
string key;
string value;
map m;
//截取日期
int pos = data.find(':', 0);
key = data.substr(0, pos);
value = data.substr(pos + 1, data.size() - pos - 1);
m.insert(make_pair(key, value));
*/
m.insert(subdata(date));
//截取时间段
m.insert(subdata(period));
//截取学生学号
m.insert(subdata(stuID));
//截取学生姓名
m.insert(subdata(stuName));
//截取机房号
m.insert(subdata(roomID));
//截取机房预约状态
m.insert(subdata(status));
//放进大容器中
m_order.insert(make_pair(this->m_Size, m));
//更新
this->m_Size++;
m.clear();//释放 存放下一条预约记录
}
ifs.close();
//测试
/*for (map>::iterator it = m_order.begin(); it != m_order.end(); it++)
{
cout << "条数为:" << it->first << "\tvalue如下:" << endl;
for (map::iterator mit = it->second.begin(); mit != it->second.end(); mit++)
{
cout << "key = " << mit->first << "\tvalue = " << mit->second << endl;
}
cout << endl << endl;
}*/
}
//截取小容器key 和 value
pair<string, string> orderFile::subdata(string data)
{
string key;
string value;
map<string, string> m;
int pos = data.find(':');
if (pos != -1)
{
key = data.substr(0, pos);
value = data.substr(pos + 1, data.size() - pos - 1);
m.insert(make_pair(key, value));
}
return make_pair(key, value);
//测试
/*cout << "key = " << key << endl;
cout << "value = " << value << endl;*/
}
小容器测试 截取每一键值对的key和value测试
读取信息测试: 看是否与order.txt信息对应上
功能描述: 更新所有预约信息,[]访问数据,这是一个map容器嵌套map容器
//更新预约机房状态函数
void orderFile::updateOrder()
{
if (this->m_Size == 0)
{
cout << "没有预约记录!" << endl;
return;
}
ofstream ofs(ORDER_FILE, ios::out | ios::trunc);
for (int i = 0; i < this->m_Size; i++)
{
cout << i + 1 << "、" << endl;
ofs << "date:" << this->m_order[i]["date"] << " ";
ofs << "period:" << this->m_order[i]["period"] << " ";
ofs << "stuID:" << this->m_order[i]["stuID"] << " ";
ofs << "stuName:" << this->m_order[i]["stuName"] << " ";
ofs << "roomID:" << this->m_order[i]["roomID"] << " ";
ofs << "status:" << this->m_order[i]["status"] << endl;
}
ofs.close();
}
解释:
this->m_order[i]
表示第i条预约信息,这是一个map容器嵌套map容器。this->m_order[i]
底层还是一个map,可以通过[]访问,通过key直接索引value实现步骤:
Student.cpp 代码展示
//查看自身预约
void Student::showmyOrder()
{
orderFile order;
if (order.m_Size == 0)
{
cout << "没有预约记录!" << endl;
system("pause");
system("cls");
return;
}
//对比学号
for (int i = 0; i < order.m_Size; i++)
{
//找到自身预约 并显示
if (this->m_Id == atoi(order.m_order[i]["stuID"].c_str()))
{
cout << "预约日期:周" << order.m_order[i]["date"];
cout << "预约时间段:" << (order.m_order[i]["period"] == "1" ? "上午" : "下午");
cout << "\t机房号:" << order.m_order[i]["roomID"];
string status = "\t状态:";
if (order.m_order[i]["status"] == "1")
{
status += "审核中";
}
else if (order.m_order[i]["status"] == "2")
{
status += "预约成功";
}
else if (order.m_order[i]["status"] == "-1")
{
status += "预约失败,审核未通过";
}
else
{
status += "预约已取消";
}
cout << status << endl;
}
}
system("pause");
system("cls");
}
注意点:
order.m_order[i]["stuID"]
,表示第i条预约记录的学生学号,这是一个string类型的数据,而自身学号是一个int类型,需要做数据类型转换才可以进行学号比较,从而找到自身预约记录。.c_str()
转成c语言风格的字符串const char *
再用atoi
转成int类型,atoi返回的是int类型,即atoi(order.m_order[i]["stuID"].c_str()
void Student::showAllOrder()
成员函数写具体实现//查看所有预约
void Student::showallOrder()
{
orderFile order;
if (order.m_Size == 0)
{
cout << "没有预约记录!" << endl;
system("pause");
system("cls");
return;
}
for (int i = 0; i < order.m_Size; i++)
{
cout << "\n第" << i + 1 << "条预约记录:";
cout << "预约日期:周" << order.m_order[i]["date"];
cout << "预约时间段:" << (order.m_order[i]["period"] == "1" ? "上午" : "下午");
cout << "\t预约学生学号:" << order.m_order[i]["stuID"];
cout << "\t预约学生姓名:" << order.m_order[i]["stuName"];
cout << "\t机房号:" << order.m_order[i]["roomID"];
string status = "\t状态:";
if (order.m_order[i]["status"] == "1")
{
status += "审核中";
}
else if (order.m_order[i]["status"] == "2")
{
status += "预约成功";
}
else if (order.m_order[i]["status"] == "-1")
{
status += "预约失败,审核未通过";
}
else
{
status += "预约已取消";
}
cout << status << endl;
}
system("pause");
system("cls");
}
测试效果如图:
实现步骤:
void Student::cancelOrder()
成员函数写具体实现Student.cpp
//取消预约
void Student::cancleOrder()
{
orderFile order;
if (order.m_Size == 0)
{
cout << "没有预约记录!" << endl;
system("pause");
system("cls");
return;
}
cout << "审核中或预约成功的记录可以取消,请输入取消的记录" << endl;
int index = 1;//记录该学生有多少条预约记录
vector v;//存放该学生符合取消条件的预约记录
//找到要取消预约的学生 以及该学生可以取消的预约记录
for (int i = 0; i < order.m_Size; i++)
{
//找到要取消预约的学生 string→const char *→int
if (atoi(order.m_order[i]["stuID"].c_str()) == this->m_Id)
{
//找到符合取消的预约记录 审核中1 预约成功2
if (order.m_order[i]["status"] == "1" || order.m_order[i]["status"] == "2")
{
//保存可以取消的预约记录的真实下标,对应m_order的key
v.push_back(i);
//展示该学生预约的所有记录 从1开始遍历 输出index 再+1
cout << index++ << "、 ";//有可能张三的记录在第一个、第二个、第四个
cout << "预约日期:周" << order.m_order[i]["date"];
cout << "预约时间段:" << (order.m_order[i]["period"] == "1" ? "上午" : "下午");
cout << "\t机房号:" << order.m_order[i]["roomID"];
string status = "\t状态:";
if (order.m_order[i]["status"] == "1")
{
status += "审核中";
}
else if (order.m_order[i]["status"] == "2")
{
status += "预约成功";
}
cout << status << endl;
}
}
}
//取消预约
cout << "请输入要取消的预约记录,0代表返回" << endl;
int select = 0;
while (true)
{
cin >> select;
//select范围:0-所有符合取消条件的预约记录的个数
if (select >= 0 && select <= v.size())
{
if (select == 0)
{
break;
}
else
{
order.m_order[v[select - 1]]["status"] = "0";
order.updateOrder();
cout << "已取消预约" << endl;
break;
}
}
else
{
cout << "输入有误,请重新输入" << endl;
}
}
system("pause");
system("cls");
}
取消预约代码思路解释:
一、找到预约记录:
如图所示,假设order.m_order容器中存放了四条记录,张三的有三条,要取消最后一条记录,也就是在order.m_order容器中删除最后一条记录。那么,怎么删除最后一条呢?进一步说,怎么获取最后一条记录的下标?
atoi(order.m_order[i]["stuID"].c_str()) == this->m_Id
,找到张三,这里的类型转变前面讲过,不赘诉order.m_order[i]["status"] == "1" || order.m_order[i]["status"] == "2"
,找到张三所有可以取消的预约记录for (int i = 0; i < order.m_Size; i++)
,index随 i 变化,即index++ 。vector v
存放的是张三可以取消的预约记录的真实下标,即对应order.m_order中的key。order.m_order[index]
找到的是李四的预约记录。因此容器v保存的是张三要取消预约记录的真实下标,即i,也即order.m_order容器中的key。v.push_back(i)
。二、预约记录怎么和用户的输入关联?
前面提到,index和select是对应的,即index是1、2、3,那么用户的选择select也只能是1、2、3。并且v中保存了对应预约记录的真实下标。找到预约记录的真实下标后,怎么和用户的选择联系起来呢?如图:
select-1
,表示v下标,通过下标找到v中保存的信息,也就是找到记录的真实下标。即v[select - 1]
,表示通过select-1
索引到v中保存的该记录的真实下标,即该记录对应在order.m_order容器的keyorder.m_order[v[select - 1]]["status"] = "0";
。最后更新容器order.m_order,并提示用户。变量说明
m_order[i]---------------------------第i条记录
i------------------------------------对应m_order容器中的key,第i条记录的真实下标
index--------------------------------对应第i条记录的顺序,从1开始,index++,随着i变化
select-------------------------------对应学生选择的可以取消的预约记录的顺序,[0, index]范围
m_order[i]["status"]=="1" / "2"-----状态为审核中/预约成功的第i条记录
v.push_back(i);----------------------存 状态为审核中/预约成功的第i条记录的 真实下标,m_order中key值
v[select - 1]------------------------对应存放在v容器中 学生选择的 顺序为select-1 预约记录的真实下标,m_order中key值
m_order[v[select - 1]]["status"]-----对应学生选择的 顺序为select-1 的预约记录的 预约状态
测试取消预约前-order.txt:
测试取消预约前-张三预约记录:
测试取消预约显示:
测试取消预约后-order.txt:
测试取消预约后-张三预约记录:
至此,学生模块功能全部实现