
无论是删除职工,查找职工,修改职工都要知道该职工是否存在并且找到该职工的位置,所以要写一个公用函数来根据输入的职工编号来返回职工的位置
/判断职工是否存在并找到位置
//无论是删除职工,查找职工,修改职工都要知道该职工是否存在,所以要写一个公用函数
//输入职工的编号,函数返回该职工的位置,要是没有该职工返回-1
int WorkerManager::Is_Exist(int id)
{
//假设没有找到
int index = -1;
for (int i = 0; i < this->m_Empnum; i++)
{
if (this->m_EmpArray[i]->m_Id == id)
{
//找到了职工所在的位置
index = i;
break;
}
}
return index;
}
由于我们之前创建的输入文件的函数save是以添加的方式将数据输入文件,所以后面的功能都不可用,我们要重新创建一个输入文件的函数save1()以out的方式打开文件来实现文件的更新(将文件中以前的数据删除,重新输入新的数据)
//将程序所有的数据重新打印到文件,实现文件的更新(文件的删除,修改都要用到)
void WorkerManager::save1()
{
ofstream ofs;
ofs.open(FILENAME, ios::out);
for (int i = 0; i < this->m_Empnum; i++)
{
ofs << this->m_EmpArray[i]->m_Id << " "
<< this->m_EmpArray[i]->m_Name << " "
<< this->m_EmpArray[i]->m_DeptId << endl;
}
//更新文件是否为空的判断
this->FileIsEmpty = false;
ofs.close();
}
知道职工的位置后我们便可以很方便的编写下面的功能
1.删除职工:
//删除职工信息
void WorkerManager::Del_Emp()
{
if (this->FileIsEmpty)
{
cout << "文件为空或文件不存在" << endl;
}
else
{
int id;
cout << "请输入需要删除职工的编号:" << endl;
cin >> id;
int index = this->Is_Exist(id);
if (index != -1)
{
int jg=1;
//找到了要删除的职工
//将要删除位置之后的数据前移
cout << "是否要删除编号为:" << this->m_EmpArray[index]->m_Id << " "
<< "姓名:" << this->m_EmpArray[index]->m_Name << "的职工" << endl;
cout << "1.是 2.否" << endl;
cin >> jg;
if (jg == 1)
{
for (int i = index; i < this->m_Empnum - 1; i++)
{
this->m_EmpArray[i] = this->m_EmpArray[i + 1];
}
//职工数量减少
this->m_Empnum--;
//将职工信息输入文件
this->save1();
cout << "删除成功" << endl;
}
else
{
cout << "取消删除" << endl;
return;
}
}
else
{
cout << "删除失败未找到该职工" << endl;
}
}
}
数组的删除就是和顺序表一样,通过数据前移来删除数据,删除职工不需要将职工从所在的数组中删除,将数据前移后,要删除的数据就会被覆盖,数组的最后一个位置便是无效的,但不用删除其中的信息,将表示职工总数目的属性减少,进行逻辑上的删除即可
2.修改职工
//修改职工信息
void WorkerManager::Mod_Emp()
{
if (this->FileIsEmpty)
{
cout << "文件为空或文件不存在" << endl;
return;
}
else
{
//文件存在且不为空
int id;
cout << "请输入要修改的职工编号" << endl;
cin >> id;
int index = this->Is_Exist(id);
if (index == -1)
{
cout << "没有找到该职工" << endl;
}
else
{
//找到职工的情况
int jg;
cout << "是否要修改编号为:" << this->m_EmpArray[index]->m_Id << " "
<< "姓名:" << this->m_EmpArray[index]->m_Name << "的职工" << endl;
cout << "1.是 2.否" << endl;
cin >> jg;
if (jg == 1)
{
//确认修改
//删除原来职工的信息
delete this->m_EmpArray[index];
cout << "请输入新职工的信息" << endl;
int new_id;
string new_name;
int new_deptid;
cout << "编号:" << endl;
cin >> new_id;
cout << "姓名:" << endl;
cin >> new_name;
cout << "部门编号:" << endl;
cout << "1.普通职工" << endl;
cout << "2.经理" << endl;
cout << "3.老板" << endl;
cin >> new_deptid;
Worker* worker = NULL;
//根据不同的部门创建不同的对象
//若是输入的编号不对便要重新输入部门编号
int DBD = 1;
while (DBD)
{
switch (new_deptid)
{
case 1:
worker = new Employee(new_id, new_name, new_deptid);
DBD = 0;
break;
case 2:
worker = new Manager(new_id, new_name, new_deptid);
DBD = 0;
break;
case 3:
worker = new Boss(new_id, new_name, new_deptid);
DBD = 0;
break;
default:
cout << "没有该部门" << endl;
}
}
//对象创建且赋值成功
//将信息保存到数组
this->m_EmpArray[index] = worker;
//将数组中发生的改变同步到文件中
this->save1();
cout << "修改成功" << endl;
}
else
{
//不确认修改
cout << "取消修改" << endl;
return;
}
}
}
}
修改职工,由于职工的部门也要进行修改,所以父类指向的子类对象也与之前不同,于是需要根据部门的编号重新创建子类对象
3.查找职工(提供两种查找方式)
//查找职工信息
//提供两种查找方式,
void WorkerManager::Find_Emp()
{
if (this->FileIsEmpty)
{
cout << "文件为空或文件不存在" << endl;
}
else
{
//文件存在
cout << "请选择通过哪种方式进行查找" << endl;
cout << "1.根据编号查找 2.根据姓名查找" << endl;
int Select;
cin >> Select;
//根据编号查找
if (Select == 1)
{
int Se_id;
cout << "请输入要查找的职工编号" << endl;
cin >> Se_id;
//调用Is_Exist()函数通过编号找到所在位置的下标
int index = this->Is_Exist(Se_id);
if (index == -1)
{
//没有查找到职工的情况
cout << "没有查找到相关职工" << endl;
}
else
{
//查找到职工的情况
cout << "查找到的职工如下:" << endl;
this->m_EmpArray[index]->ShowInfo();
}
}
//根据姓名查找
else if (Select == 2)
{
cout << "请输入要查找的职工姓名:" << endl;
string Se_name;
cin >> Se_name;
//要考虑有重名的情况,将所有重名的人都打印出来
//所以无论有没有找到,都要遍历完所有的数据
//定义一个判断是否找到相关职工的判断标志
bool find = false;
cout << "查找的结果为:" << endl;
for (int i = 0; i < this->m_Empnum; i++)
{
//找到了相应的名字
if (this->m_EmpArray[i]->m_Name == Se_name)
{
//查找到了直接调用每个子类都有的ShowInfo()函数打印出信息
this->m_EmpArray[i]->ShowInfo();
cout << endl;
//找到就改变判断标准
find = true;
}
}
//判断标准为false,没有找到相关职工的情况
if (find == false)
{
cout << "没有找到相关职工" << endl;
}
}
else
{
cout << "输入无效" << endl;
}
}
}
注意根据名字查找的是有重名的现象的,所以不能和编号一样,查找到相应编号后便可以退出循环,要遍历完所有的职工才能退出循环
4.按照职工编号进行排序
//按照职工编号进行排序
void WorkerManager::Sort_Emp()
{
//文件为空的情况
if (this->FileIsEmpty)
{
cout << "文件不存在或文件为空" << endl;
}
else
{
cout << "请选择按什么方式排序:" << endl;
cout << "1.升序 2.降序" << endl;
int select;
cin >> select;
//记录最小编号职员所在位置的下标
int minormax;
//对职员编号进行排序通过选择排序的方法
for (int i = 0; i < this->m_Empnum; i++)
{
//假设一开始的i处是最小的/最大的编号的下标
minormax = i;
//让i与后面的所有数进行比较找出最小的数
for (int j = i + 1; j < this->m_Empnum; j++)
{
//因为无论是升序还是降序都要进行双重for循环,所以让升序和降序的双重for循环通用
if (select == 1)
{
//判断最小的职员编号
if (this->m_EmpArray[j]->m_Id < this->m_EmpArray[minormax]->m_Id)
{
//更新minormax,让minormax表示最小位置的下标
minormax = j;
//结束循环后便获得了升序的
}
}
else if (select == 2)
{
//判断最大的职员编号
if (this->m_EmpArray[j]->m_Id > this->m_EmpArray[minormax]->m_Id)
{
minormax = j;
}
}
else
{
cout << "输入有误" << endl;
return;
}
//当我们一开始设立的第一个位置的最小值/最大值不正确,在遍历获得真正的最小值/最大值后,要将他们的位置进行交换
if (minormax != i)
{
Worker* temp;
temp = this->m_EmpArray[i];
this->m_EmpArray[i] = this->m_EmpArray[minormax];
this->m_EmpArray[minormax] = temp;
}
}
}
//在程序中将顺序排好后再打印进文件中
this->save1();
cout << "排序成功,排序结果为:" << endl;
//调用打印函数打印相应内容
this->Show_Emp();
}
}
选择排序和冒泡排序都可以进行数据升序降序的排序,但是选择排序的数据交换频率比冒泡排序少很多,冒泡排序是一直进行前后信息的比较,交换,将最大或最小的数据移动到相应位置。选择排序是遍历找到数据中的最大或最小值,然后再把最值交换到应该在的位置
5.清空职工信息
//清空职工信息
void WorkerManager::Clear_Emp()//清空职工信息
{
int select;
cout << "是否确认清空" << endl;
cout << "1.是 2.否" << endl;
cin >> select;
if (select == 1)
{
//清空文件中的职工信息
ofstream ofs;
//用trunc的方式打开文件,当已经存在该文件时会将文件删除再重新创建
ofs.open(FILENAME, ios::trunc);
//释放堆区中的内存
if (this->m_EmpArray != NULL)
{
for (int i = 0; i < this->m_Empnum; i++)
{
if (this->m_EmpArray[i] != NULL)
{
delete this->m_EmpArray[i];
}
}
delete[] this->m_EmpArray;
this->m_EmpArray = NULL;
//更新表示文件状态的标志
this->FileIsEmpty = true;
cout << "清空成功" << endl;
}
}
else if (select == 2)
{
cout << "取消清空" << endl;
}
else
{
cout << "输入错误" << endl;
}
}
上篇
https://blog.csdn.net/q322359/article/details/127008682?spm=1001.2014.3001.5501
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)