实现步骤:
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;//初始化为0while ( 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 m;//截取日期/*//截取key value值并存入map小容器中 统一用stringstring 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 orderFile::subdata(string data)
{string key;string value;map 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 *→intif (atoi(order.m_order[i]["stuID"].c_str()) == this->m_Id){//找到符合取消的预约记录 审核中1 预约成功2if (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,并提示用户。测试取消预约前-order.txt:
测试取消预约前-张三预约记录:
测试取消预约显示:
测试取消预约后-order.txt:
测试取消预约后-张三预约记录:
至此,学生模块功能全部实现