职工管理系统(C++多态案例)(信息的删除,修改,查找,排序......)

职工管理系统(C++多态案例)(信息的删除,修改,查找,排序......),第1张

      无论是删除职工,查找职工,修改职工都要知道该职工是否存在并且找到该职工的位置,所以要写一个公用函数来根据输入的职工编号来返回职工的位置

/判断职工是否存在并找到位置
//无论是删除职工,查找职工,修改职工都要知道该职工是否存在,所以要写一个公用函数
//输入职工的编号,函数返回该职工的位置,要是没有该职工返回-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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/langs/3002529.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-09-27
下一篇2022-09-27

发表评论

登录后才能评论

评论列表(0条)

    保存