OrderFile类成员函数
创建OrderFile类,用于对预约记录(文本文件order.txt)进行数据读写。
class OrderFile
{
public:
//构造函数
OrderFile();
//更新预约记录
void updateOrder();
//记录的容器 key---记录的条数 value---具体记录的键值对信息
map<int, map<string, string>>m_OrderData;
//预约记录条数
int m_size;
};
map容器m_OrderData用于存放从order.txt中读取的信息。order.txt中信息存储格式如下:
m_OrderData的key值表示记录的条数次序,value值也是map容器,表示该条记录的6个键值对(例如"date:“和"1”)。
1、OrderFile的构造函数
在构造函数中打开order.txt文件,将其中记录以字符串的形式写入m_OrderData容器。
//构造函数
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; //记录条数
//ifs以>>的形式读取时,以空格“ ”为间隔,一次读取一个字符串
while (ifs >> date && ifs >> interval && ifs >> stuId && ifs >> stuName && ifs >> roomId
&& ifs >> status)
{
string key;
string value;
map<string, string>m;
//截取日期
//此时读取的date是"date:1",找到冒号“:”的位置,截取为两个子串“data”和"1",分别放进map<string,string>m的key和value中
int pos = date.find(":");
if (pos != -1)
{
key = date.substr(0, pos);
value = date.substr(pos + 1, date.size() - pos-1);
//cout << "key=" << key << endl;
//cout << "value=" << value << endl;
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);
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);
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);
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);
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);
m.insert(make_pair(key, value));
}
//将小map容器放到大的map容器中
this->m_OrderData.insert(make_pair(this->m_size, m));
this->m_size++;
}
ifs.close();
2、void Update Order()
将order.txt文件删除重建,再写入m_OrderData的内容,从而更新order.txt中的预约记录
//更新预约记录
void OrderFile::updateOrder()
{
if (this->m_size == 0)
{
return;
}
ofstream ofs;
ofs.open(ORDER_FILE, ios::out | ios::trunc);
for (int i = 0; i < m_size; i++)
{
ofs << "date:" << m_OrderData[i]["date"] << " ";
ofs << "interval:" << m_OrderData[i]["interval"] << " ";
ofs << "stuId:" << m_OrderData[i]["stuId"] << " ";
ofs << "stuName:" << m_OrderData[i]["stuName"] << " ";
ofs << "roomId:" << m_OrderData[i]["roomId"] << " ";
ofs << "status:" << m_OrderData[i]["status"] << endl;
}
ofs.close();
}
Manager管理员类
1、构造函数
在Manager类的有参构造函数中,给name、password赋值,同时调用this->initVector()函数,把student.txt和teacher.txt中存储的学生教师账号信息全读入容器vStu和vTea中。再把computerRoom.txt中存储的机房信息读入容器vCom中。
//有参构造函数(职工编号、姓名、密码)
Manager::Manager(string name, string pwd)
{
//初始化管理员信息
this->m_Name = name;
this->m_Pwd = pwd;
//初始化容器,获取到所有文件中学生、老师信息
this->initVector();
ifstream ifs;
ifs.open(COMPUTER_FILE, ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败!" << endl;
return;
}
ComputerRoom c;
while (ifs >> c.m_ComId && ifs >> c.m_MaxNum)
{
this->vCom.push_back(c);
}
cout << "当前机房数量为:" << this->vCom.size() << endl;
ifs.close();
}
void Manager::initVector()
{
this->vStu.clear();
this->vTea.clear();
ifstream ifs;
//读取学生文件信息
ifs.open(STUDENT_FILE, ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败!" << endl;
return;
}
Student s;
while (ifs >>s.m_Id && ifs >> s.m_Name && ifs >> s.m_Pwd)
{
this->vStu.push_back(s);
}
//cout << "当前学生人数为:" << this->vStu.size() << endl;
ifs.close();
//读取教师文件信息
ifs.open(TEACHER_FILE, ios::in);
if (!ifs.is_open())
{
cout << "文件打开失败!" << endl;
return;
}
Teacher t;
while (ifs >> t.m_EmpId && ifs >> t.m_Name && ifs >> t.m_Pwd)
{
this->vTea.push_back(t);
}
//cout << "当前教师人数为:" << this->vTea.size() << endl;
ifs.close();
}
2、bool checkRepeat(int id,int type)
type表示身份,type=1时为学生,type=2时为教师。id表示学号或者教师职工编号。此函数用于检测管理员添加账号时输入的id号是否和账号记录中已有的id号重复。若type=1,则遍历vStu容器,检测形参id是否和容器中存储的Student对象的id重复;若type=2,则遍历vTea容器。
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 if (type == 2)
{
for (vector<Teacher>::iterator it = vTea.begin(); it != vTea.end(); it++)
{
if (id == (*it).m_EmpId)
{
return true;
}
}
}
return false;
}
3、添加账号void Manager::addPerson()
//添加账号
void Manager::addPerson()
{
cout << "请输入添加账号的类型" << endl;
cout << "1、添加学生" << endl;
cout << "2、添加教师" << endl;
int select = 0; //接收用户的选择
string filename; //操作文件名
string tip; //提示id号
ofstream ofs; //文件操作对象
string errorTip; //重复错误提示
while (1)
{
cin >> select;
if (select == 1)
{
//添加的是学生
filename = STUDENT_FILE;
tip = "请输入学号:";
errorTip = "学号重复,请重新输入";
break;
}
else if (select == 2)
{
//添加的是教师
filename = TEACHER_FILE;
tip = "请输入职工编号:";
errorTip = "职工编号重复,请重新输入";
break;
}
else
{
cout << "选择错误,请重新选择:" << endl;
}
}
//利用追加的方式写文件
ofs.open(filename, ios::out | ios::app);
int id; //学号或者职工编号
string name;
string pwd;
cout << tip;
while (1)
{
cin >> id;
bool ret = this->checkRepeat(id, select);
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();
}
4、查看账号
利用for_each算法,遍历vTea和vStu容器,输出容器中内容。
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(this->vStu.begin(), vStu.end(), printStudent);
}
else
{
//查看所有老师
cout << "所有教师的信息如下:" << endl;
for_each(this->vTea.begin(), vTea.end(), printTeacher);
}
system("pause");
system("cls");
}
5、查看机房
遍历vCom容器,输出即可。
//查看机房信息
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");
}
6、清空预约记录
删除重建order.txt文件即可。
//清空预约记录
void Manager::cleanFile()
{
ofstream ofs;
ofs.open(ORDER_FILE, ios::trunc);
ofs.close();
cout << "清空成功!" << endl;
system("pause");
system("cls");
}