需求
文件目录
代码
机房预约系统.cpp
#include<iostream>
#include "Identity.h"
#include<fstream>
#include<string>
#include "globalFile.h"
#include "student.h"
#include "teacher.h"
#include "manager.h"
using namespace std;// 使用指针引用 Identity*& manager 可以让函数内部对指针的修改直接影响到调用者的原始指针,
// 避免悬空指针问题,保证资源管理的正确性和代码逻辑的一致性。
// 指针作为参数传递的特性:当你将一个指针作为普通参数传递给函数时,
// 传递的是指针的值(即指针所存储的内存地址)的副本。在函数内部对这个副本进行修改,
// 不会影响到原始指针本身
void managerMenu(Identity*& manager) {while (true) {manager->openMenu();Manager* man = (Manager*)manager;int select = 0;cin >> select;if (select == 1) {cout << "添加账号" << endl;man->addPerson();}else if (select == 2) {cout << "查看账号" << endl;man->showPerson();}else if (select == 3) {cout << "查看机房" << endl;man->showComputer();}else if (select == 4) {cout << "清空预约" << endl;man->cleanFile();}else {delete manager;cout << "注销成功" << endl;system("pause");system("cls");return;}}
}void studentMenu(Identity*& student) {while (true) {//学生菜单student->openMenu();Student* stu = (Student*)student;int select = 0;cin >> select;if (select == 1) {stu->applyOrder();}else if (select == 2) {stu->showMyOrder();}else if (select == 3) {stu->showAllOrder();}else if (select == 4) {stu->cancelOrder();}else {delete student;cout << "注销成功" << endl;system("pause");system("cls");return;}}
}void teacherMenu(Identity*& teacher)
{while (true) {//教师菜单teacher->openMenu();Teacher* tea = (Teacher*)teacher;int select = 0;cin >> select;if (select == 1) {//查看所有预约tea->showAllOrder();}else if (select == 2) {//审核预约tea->validOrder();}else {delete teacher;cout << "注销成功" << endl;system("pause");system("cls");return;}}
}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) {int fId;string fName;string fPwd;while (ifs >> fId && ifs >> fName && ifs >> fPwd) {if (id == fId && name == fName && pwd == fPwd) {cout << "学生验证登录成功!" << endl;system("pause");system("cls");person = new Student(id, name, pwd);studentMenu(person);return;}}}else if (type == 2) {int fId;string fName;string fPwd;while (ifs >> fId && ifs >> fName && ifs >> fPwd){if (id == fId && name == fName && pwd == fPwd){cout << "教师验证登录成功!" << endl;system("pause");system("cls");person = new Teacher(id, name, pwd);teacherMenu(person);return;}}}else {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);managerMenu(person);return;}}}cout << "验证登录失败!" << endl;system("pause");system("cls");return;
}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: // 学生身份LoginIn(STUDENT_FILE, 1);break;case 2: // 老师身份LoginIn(TEACHER_FILE, 2);break;case 3: // 管理员身份LoginIn(ADMIN_FILE, 3);break;case 0: // 退出系统cout << "欢迎下一次使用!" << endl;system("pause");return 0;break;default:cout << "输入有误,请重新选择!" << endl;system("pause");system("cls");break;}}system("pause");return 0;
}
Identity.h
#pragma once
#include<iostream>
using namespace std;class Identity {public:string m_Name;string m_Pwd;public:virtual void openMenu() = 0;};
manager.h
#pragma once
#include<iostream>
#include "Identity.h"
#include<fstream>
#include "globalFile.h"
#include<vector>
#include "student.h"
#include "teacher.h"
#include<algorithm>
#include "computerRoom.h"
using namespace std;class Manager : public Identity {public://学生容器vector<Student> vStu;//教师容器vector<Teacher> vTea;vector<ComputerRoom> vCom;public:Manager();Manager(string name, string pwd);virtual void openMenu();void addPerson();void showPerson();void showComputer();void cleanFile();void initVector();bool checkRepeat(int id, int type);
};
manager.cpp
#include "manager.h"Manager::Manager() {}Manager::Manager(string name, string pwd) {this->m_Name = name;this->m_Pwd = pwd;this->initVector();//获取机房信息ifstream ifs;ifs.open(COMPUTER_FILE, ios::in);ComputerRoom c;while (ifs >> c.m_ComId && ifs >> c.m_MaxNum){vCom.push_back(c);}cout << "当前机房数量为: " << vCom.size() << endl;ifs.close();
}void Manager::openMenu() {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;
}void Manager::addPerson() {cout << "请输入添加账号的类型" << endl;cout << "1、添加学生" << endl;cout << "2、添加老师" << endl;string fileName;string tip;string errorTip; //重复错误提示ofstream ofs;int select = 0;cin >> select;if (select == 1){fileName = STUDENT_FILE;tip = "请输入学号: ";errorTip = "学号重复,请重新输入";}else{fileName = TEACHER_FILE;tip = "请输入职工编号:";errorTip = "职工号重复,请重新输入";}ofs.open(fileName, ios::out | ios::app);int id;string name;string pwd;cout << tip << endl;while (true) {cin >> id;bool ret = this->checkRepeat(id, 1);if (ret) //有重复{cout << errorTip << endl;}else{break;}}cout << "请输入姓名: " << endl;cin >> name;cout << "请输入密码: " << endl;cin >> pwd;ofs << id << " " << name << " " << pwd << " " << endl;cout << "添加成功" << endl;system("pause");system("cls");ofs.close();this->initVector();
}void printStudent(Student& s)
{cout << "学号: " << s.m_Id << " 姓名: " << s.m_Name << " 密码:" << s.m_Pwd << endl;
}
void printTeacher(Teacher& t)
{cout << "职工号: " << t.m_EmpId << " 姓名: " << t.m_Name << " 密码:" << t.m_Pwd << endl;
}void Manager::showPerson() {cout << "请选择查看内容:" << endl;cout << "1、查看所有学生" << endl;cout << "2、查看所有老师" << endl;int select = 0;cin >> select;if (select == 1){cout << "所有学生信息如下: " << endl;for_each(vStu.begin(), vStu.end(), printStudent);}else{cout << "所有老师信息如下: " << endl;for_each(vTea.begin(), vTea.end(), printTeacher);}system("pause");system("cls");
}void Manager::showComputer() {cout << "机房信息如下: " << endl;for (vector<ComputerRoom>::iterator it = vCom.begin(); it != vCom.end(); it++) {cout << "机房编号: " << it->m_ComId << " 机房最大容量: " << it->m_MaxNum << endl;}system("pause");system("cls");
}void Manager::cleanFile() {ofstream ofs(ORDER_FILE, ios::trunc);ofs.close();cout << "清空成功!" << endl;system("pause");system("cls");
}void Manager::initVector() {//读取学生文件中信息ifstream ifs;ifs.open(STUDENT_FILE, ios::in);if (!ifs.is_open()){cout << "文件读取失败" << endl;return;}vStu.clear();vTea.clear();Student s;while (ifs >> s.m_Id && ifs >> s.m_Name && ifs >> s.m_Pwd){vStu.push_back(s);}//cout << "当前学生数量为: " << vStu.size() << endl;ifs.close(); //学生初始化//读取老师文件信息ifs.open(TEACHER_FILE, ios::in);Teacher t;while (ifs >> t.m_EmpId && ifs >> t.m_Name && ifs >> t.m_Pwd){vTea.push_back(t);}//cout << "当前教师数量为: " << vTea.size() << endl;ifs.close();
}bool Manager::checkRepeat(int id, int type) {if (type == 1){for (vector<Student>::iterator it = vStu.begin(); it != vStu.end(); it++){if (id == it->m_Id){return true;}}}else{for (vector<Teacher>::iterator it = vTea.begin(); it != vTea.end(); it++){if (id == it->m_EmpId){return true;}}}return false;
}
student.h
#pragma once
#include<iostream>
#include "Identity.h"
#include<vector>
#include "computerRoom.h"
#include<fstream>
#include "globalFile.h"
#include "orderFile.h"
using namespace std;class Student :public Identity {public:int m_Id;vector<ComputerRoom> vCom;public:Student();Student(int id, string name, string pwd);virtual void openMenu();void applyOrder();void showMyOrder();void showAllOrder();void cancelOrder();};
student.cpp
#include "student.h"Student::Student() {}Student::Student(int id, string name, string pwd) {//初始化属性this->m_Id = id;this->m_Name = name;this->m_Pwd = pwd;ifstream ifs;ifs.open(COMPUTER_FILE, ios::in);ComputerRoom c;while (ifs >> c.m_ComId && ifs >> c.m_MaxNum) {vCom.push_back(c);}ifs.close();
}void Student::openMenu()
{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;
}void Student::applyOrder() {cout << "机房开放时间为周一至周五!" << endl;cout << "请输入申请预约的时间:" << endl;cout << "1、周一" << endl;cout << "2、周二" << endl;cout << "3、周三" << endl;cout << "4、周四" << endl;cout << "5、周五" << endl;int date = 0;int interval = 0;int room = 0;while (true) {cin >> date;if (date >= 1 && date <= 5) {break;}cout << "输入有误,请重新输入" << endl;}cout << "请输入申请预约的时间段:" << endl;cout << "1、上午" << endl;cout << "2、下午" << endl;while (true) {cin >> interval;if (interval >= 1 && interval <= 2) {break;}cout << "输入有误,请重新输入" << endl;}cout << "请选择机房:" << endl;cout << "1号机房容量:" << vCom[0].m_MaxNum << endl;cout << "2号机房容量:" << vCom[1].m_MaxNum << endl;cout << "3号机房容量:" << vCom[2].m_MaxNum << endl;while (true) {cin >> room;if (room >= 1 && room <= 3) {break;}cout << "输入有误,请重新输入" << endl;}cout << "预约成功!审核中" << endl;ofstream ofs(ORDER_FILE, ios::app);ofs << "date:" << date << " ";ofs << "interval:" << interval << " ";ofs << "stuId:" << this->m_Id << " ";ofs << "stuName:" << this->m_Name << " ";ofs << "roomId:" << room << " ";ofs << "status:" << 1 << endl;ofs.close();system("pause");system("cls");
}void Student::showAllOrder() {OrderFile of;if (of.m_Size == 0) {cout << "无预约记录" << endl;system("pause");system("cls");return;}for (int i = 0; i < of.m_Size; i++) {cout << i + 1 << "、 ";cout << "预约日期: 周" << of.m_orderData[i]["date"];cout << " 时段:" << (of.m_orderData[i]["interval"] == "1" ? "上午" : "下午");cout << " 学号:" << of.m_orderData[i]["stuId"];cout << " 姓名:" << of.m_orderData[i]["stuName"];cout << " 机房:" << of.m_orderData[i]["roomId"];string status = " 状态: "; // 0 取消的预约 1 审核中 2 已预约 -1 预约失败if (of.m_orderData[i]["status"] == "1") {status += "审核中";}else if (of.m_orderData[i]["status"] == "2") {status += "预约成功";}else if (of.m_orderData[i]["status"] == "-1") {status += "审核未通过,预约失败";}else {status += "预约已取消";}cout << status << endl;}system("pause");system("cls");
}void Student::cancelOrder() {OrderFile of;if (of.m_Size == 0) {cout << "无预约记录" << endl;system("pause");system("cls");return;}cout << "审核中或预约成功的记录可以取消,请输入取消的记录" << endl;vector<int> v;int index = 1;for (int i = 0; i < of.m_Size; i++) {if (atoi(of.m_orderData[i]["stuId"].c_str()) == this->m_Id) {if (of.m_orderData[i]["status"] == "1" || of.m_orderData[i]["status"] == "2") {v.push_back(i);cout << index++ << "、 ";cout << "预约日期: 周" << of.m_orderData[i]["date"];cout << " 时段:" << (of.m_orderData[i]["interval"] == "1" ? "上午" : "下午");cout << " 机房:" << of.m_orderData[i]["roomId"];string status = " 状态: "; // 0 取消的预约 1 审核中 2 已预约 -1 预约失败if (of.m_orderData[i]["status"] == "1") {status += "审核中";}else if (of.m_orderData[i]["status"] == "2") {status += "预约成功";}cout << status << endl;}}}cout << "请输入取消的记录,0代表返回" << endl;int select = 0;while (true) {cin >> select;if (select >= 0 && select <= v.size()) {if (select == 0) {break;}else {// cout << "记录所在位置: " << v[select - 1] << endl;of.m_orderData[v[select - 1]]["status"] = "0";of.updateOrder();cout << "已取消预约" << endl;break;}}cout << "输入有误,请重新输入" << endl;}system("pause");system("cls");
}void Student::showMyOrder() {OrderFile of;if (of.m_Size == 0) {cout << "无预约记录" << endl;system("pause");system("cls");return;}for (int i = 0; i < of.m_Size; i++) {// c_str() 是 std::string 类的一个成员函数,其作用是返回一个指向以空字符结尾的// C 风格字符串的指针。由于 atoi 函数要求传入的参数是 C 风格字符串,// 所以需要使用 c_str() 进行转换。// atoi 是 C 标准库中的一个函数,其全称为 ascii to integer,// 功能是把 C 风格字符串转换为整数。它会从字符串的起始位置开始解析,// 直到遇到非数字字符或者字符串结束符 '\0' 为止,然后返回解析得到的整数值。if (atoi(of.m_orderData[i]["stuId"].c_str()) == this->m_Id) {cout << "预约日期: 周" << of.m_orderData[i]["date"];cout << " 时段:" << (of.m_orderData[i]["interval"] == "1" ? "上午" : "下午");cout << " 机房:" << of.m_orderData[i]["roomId"];string status = " 状态: "; // 0 取消的预约 1 审核中 2 已预约 -1 预约失败if (of.m_orderData[i]["status"] == "1") {status += "审核中";}else if (of.m_orderData[i]["status"] == "2") {status += "预约成功";}else if (of.m_orderData[i]["status"] == "-1") {status += "审核未通过,预约失败";}else {status += "预约已取消";}cout << status << endl;}}system("pause");system("cls");
}
teacher.h
#pragma once
#include<iostream>
#include "Identity.h"
#include "orderFile.h"
#include<vector>
using namespace std;/*
* 在 Visual Studio 中,微软为了提高程序的安全性,
对一些传统的 C 标准库函数进行了标记,认为这些函数存在潜在的安全风险,
例如 strcpy、gets、sprintf 等。当你使用这些函数时,
编译器会发出安全警告,提示你使用更安全的替代函数,如 strcpy_s、fgets、sprintf_s 等。
#define _CRT_SECURE_NO_WARNINGS 的作用就是告诉编译器忽略这些安全警告,
允许你继续使用传统的 C 标准库函数。这样做可以避免在编译过程中出现大量的警告信息,
让你专注于代码的功能实现。
*/
#define _CRT_SECURE_NO_WARNINGSclass Teacher : public Identity {public:int m_EmpId;public:Teacher();Teacher(int empId, string name, string pwd);virtual void openMenu();void showAllOrder();void validOrder();};
teacher.cpp
#include "teacher.h"Teacher::Teacher() {}Teacher::Teacher(int empId, string name, string pwd) {this->m_EmpId = empId;this->m_Name = name;this->m_Pwd = pwd;
}void Teacher::openMenu() {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| 0.注销登录 |\n";cout << "\t\t| |\n";cout << "\t\t ----------------------------------\n";cout << "请选择您的操作: " << endl;
}void Teacher::showAllOrder() {OrderFile of;if (of.m_Size == 0) {cout << "无预约记录" << endl;system("pause");system("cls");return;}for (int i = 0; i < of.m_Size; i++) {cout << i + 1 << "、 ";cout << "预约日期: 周" << of.m_orderData[i]["date"];cout << " 时段:" << (of.m_orderData[i]["interval"] == "1" ? "上午" : "下午");cout << " 学号:" << of.m_orderData[i]["stuId"];cout << " 姓名:" << of.m_orderData[i]["stuName"];cout << " 机房:" << of.m_orderData[i]["roomId"];string status = " 状态: "; // 0 取消的预约 1 审核中 2 已预约 -1 预约失败if (of.m_orderData[i]["status"] == "1") {status += "审核中";}else if (of.m_orderData[i]["status"] == "2") {status += "预约成功";}else if (of.m_orderData[i]["status"] == "-1") {status += "审核未通过,预约失败";}else {status += "预约已取消";}cout << status << endl;}system("pause");system("cls");
}void Teacher::validOrder() {OrderFile of;if (of.m_Size == 0){cout << "无预约记录" << endl;system("pause");system("cls");return;}cout << "待审核的预约记录如下:" << endl;vector<int>v;int index = 0;for (int i = 0; i < of.m_Size; i++) {if (of.m_orderData[i]["status"] == "1") {v.push_back(i);cout << ++index << "、 ";cout << "预约日期: 周" << of.m_orderData[i]["date"];cout << " 时段:" << (of.m_orderData[i]["interval"] == "1" ? "上午" : "下午");cout << " 机房:" << of.m_orderData[i]["roomId"];string status = " 状态: "; // 0取消的预约 1 审核中 2 已预约 -1 预约失败if (of.m_orderData[i]["status"] == "1") {status += "审核中";}cout << status << endl;}}cout << "请输入审核的预约记录,0代表返回" << endl;int select = 0;int ret = 0;while (true) {cin >> select;if (select >= 0 && select <= v.size()) {if (select == 0) {break;}else {cout << "请输入审核结果" << endl;cout << "1、通过" << endl;cout << "2、不通过" << endl;cin >> ret;if (ret == 1) {of.m_orderData[v[select - 1]]["status"] = "2";}else {of.m_orderData[v[select - 1]]["status"] = "-1";}of.updateOrder();cout << "审核完毕!" << endl;break;}}cout << "输入有误,请重新输入" << endl;}system("pause");system("cls");
}
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"
orderFile.h
#pragma once
#include<iostream>
#include<map>
#include "globalFile.h"
#include<fstream>
using namespace std;class OrderFile {
public://构造函数OrderFile();//更新预约记录void updateOrder();//记录的容器 key --- 记录的条数 value --- 具体记录的键值对信息map<int, map<string, string>> m_orderData;//预约记录条数int m_Size;
};
orderFile.cpp
#include "orderFile.h"OrderFile::OrderFile() {ifstream ifs;ifs.open(ORDER_FILE, ios::in);string date; //日期string interval; //时间段string stuId; //学生编号string stuName; //学生姓名string roomId; //机房编号string status; //预约状态this->m_Size = 0; //预约记录个数while (ifs >> date && ifs >> interval && ifs >> stuId && ifs >> stuName && ifs >> roomId && ifs >> status) {string key;string value;map<string, string> m;int pos = date.find(":");if (pos != -1) {key = date.substr(0, pos);value = date.substr(pos + 1, date.size() - pos - 1);m.insert(make_pair(key, value));}pos = interval.find(":");if (pos != -1) {key = interval.substr(0, pos);value = interval.substr(pos + 1, interval.size() - pos - 1);m.insert(make_pair(key, value));}pos = stuId.find(":");if (pos != -1) {key = stuId.substr(0, pos);value = stuId.substr(pos + 1, stuId.size() - pos - 1);m.insert(make_pair(key, value));}pos = stuName.find(":");if (pos != -1) {key = stuName.substr(0, pos);value = stuName.substr(pos + 1, stuName.size() - pos - 1);m.insert(make_pair(key, value));}pos = roomId.find(":");if (pos != -1) {key = roomId.substr(0, pos);value = roomId.substr(pos + 1, roomId.size() - pos - 1);m.insert(make_pair(key, value));}pos = status.find(":");if (pos != -1) {key = status.substr(0, pos);value = status.substr(pos + 1, status.size() - pos - 1);m.insert(make_pair(key, value));}this->m_orderData.insert(make_pair(this->m_Size, m));this->m_Size++;}ifs.close();
}void OrderFile::updateOrder() {if (this->m_Size == 0) {return;}ofstream ofs(ORDER_FILE, ios::out | ios::trunc);for (int i = 0; i < m_Size;i++) {ofs << "date:" << this->m_orderData[i]["date"] << " ";ofs << "interval:" << this->m_orderData[i]["interval"] << " ";ofs << "stuId:" << this->m_orderData[i]["stuId"] << " ";ofs << "stuName:" << this->m_orderData[i]["stuName"] << " ";ofs << "roomId:" << this->m_orderData[i]["roomId"] << " ";ofs << "status:" << this->m_orderData[i]["status"] << endl;}ofs.close();
}