c++基础(十七)——职工管理系统实现

一、项目的创建

打开visual studio之后,选择文件—新建—项目。出现弹窗后选择Visual C++,填好名称即可。
在这里插入图片描述
接下来分别在对应的位置创建头文件以及源文件以及一个主函数文件"职工管理系统.cpp":
在这里插入图片描述

二、系统界面的基本实现:

在头文件种先导入我们需要使用的基础包,这里主要是使用#pragma once、#include 以及标准的输入输出流using namespace std;
包导入完成之后先实现一个基础类,类中包含基础类的构造函数以及析构函数,并且创建一个类内的展示菜单函数。
具体的实现如下:

#pragma once  //防止头文件重复包含
#include<iostream>  //包含输入输出流的头文件
using namespace std; //使用标准的命名空间

class workerManager
{
public:
	//构造函数
	workerManager();

	//展示菜单
	void show_Menu();


	//析构函数
	~workerManager();
};

在源文件中需要写好具体的函数实现,在实现之前需要将直接写好的头文件导入到源文件中,再将workerManager类中的构造函数以及析构函数的基本实现写在该文件中,最后实现一下展示菜单的基本功能。

#include"workerManager.h"

workerManager::workerManager()
{
	//这是构造函数
}

workerManager::~workerManager()
{
	//这是析构函数
}
//这是展示菜单
void workerManager::show_Menu()
{
	cout << "***************************************" << endl;
	cout << "*******欢迎使用职工管理系统************" << endl;
	cout << "***********0.退出管理程序**************" << endl;
	cout << "***********1.增加职工信息**************" << endl;
	cout << "***********2.显示职工信息**************" << endl;
	cout << "***********3.删除职工信息**************" << endl;
	cout << "***********4.修改职工信息**************" << endl;
	cout << "***********5.查找职工信息**************" << endl;
	cout << "***********6.按照编号排序**************" << endl;
	cout << "***********7.清空所有文档**************" << endl;
	cout << endl;
}

三、退出管理系统的基本实现:

在项目主函数中实现一个用户的输入并且写入一个while循环,通过switch语句实现选择的功能。具体的代码如下:

int main() {

	//实例化管理者对象
	workerManager wm;
	int choise = 0; //用户的选择选项
	while (true)
	{
		wm.show_Menu();
		cout << "请输入您要选择的功能" << endl;
		cin >> choise;
		switch (choise)
		{

		case 0: //退出系统
			wm.exitSystem();
			break;
		case 1: //增加职工信息
			break;
		case 2: //显示职工信息
			break;
		case 3: //删除职工信息
			break;
		case 4: //修改职工信息
			break;
		case 5: //查找职工信息
			break;
		case 6: //按照编号排序
			break;
		case 7: //清空所有文档
			break;
		default:
			system("cls");
			break;
		}
	}
	system("pause");
	return 0;
}

此时我们还需要在workerManager类中实现一个退出程序的函数实现,在头文件中的workerManager类中写入一个函数的声明:

	//退出程序的函数
	void exitSystem();

在源文件中写入一个exitSystem()函数的具体实现:

void workerManager::exitSystem()
{
	cout << "欢迎下次使用" << endl;
	system("pause");
	exit(0); // 退出程序
}

四、创建一个职工的类

现在需要使用我们多态的内容,我们先构建一个员工的基类"worker",创建一个头文件:worker.h。该类的主要属性为:职工的编号、姓名、以及所在的部门,该类还要实现一个显示个人信息以及岗位名称的一个基本功能,其基类的样例如下:

#pragma once
#include<iostream>
#include<string>
using namespace std;

//职工类
class worker
{
public:
	//显示个人信息
	virtual void showInfo() = 0;

	//显示岗位名称
	virtual string getDeptName() = 0;

	//职工编号
	int m_ID;

	//职工姓名
	string m_name;

	//职工所在的部门编号
	int DeptId;
};

实现完员工的基类之后我们需要先完成一个基本员工的子类,我们先实现一个头文件,其代码如下:

//普通员工文件
#pragma once
#include<iostream>
#include"worker.h"
using namespace std;

class Employee:public worker
{
public:
	//构造函数
	Employee(int id, string name, int dID);

	//显示个人信息
	void showInfo();

	//显示岗位名称
	string getDeptName();
};

接下来我们通过源文件分别实现其构造函数以及显示个人信息、显示岗位名称的基本实现。其代码如下:

#include"employee.h"

//构造函数的实现
Employee::Employee(int id, string name, int dID)
{
	this->m_ID = id;
	this->m_name = name;
	this->m_ID = dID;
}

显示个人信息
void Employee::showInfo()
{
	cout << "职工的编号:   " << this->m_ID
		<< "\t职工的名字:   " << this->m_name
		<< "\t职工的岗位:   " << this->getDeptName()
		<< "\t岗位的职责:   " << "完成经理交给的任务" << endl;

}

//显示岗位名称
string Employee::getDeptName()
{
	return string("员工");
}

经理以及老板类的实现就不再列出了,内容同上。

五、创建添加职工管理功能

在添加新功能之前吗,我们先要明确一下我们要实现什么功能,假设我们的系统中已经有了数据存储了,我们需要一个现有员工的数量,由于我们需要将不同种类的员工添加到同一系统中,此时我们可以通过基类:worker的指针指向一个存放指针的数组中,所以我们还需要一个数组:worker ** m_EmpArray;

	//记录职工的人数
	int m_EmpNum;

	//职工数组指针
	worker ** m_EmpArray;

	//添加职工
	void Add_Emp();

以下为新加员工数据的一个函数实现,首先我们需要确定用于需要添加多少新员工,之后判断用户是否输入正确,如果正确,则继续,如果错误则提示有误。当用户输正确之后,我们需要确定以下我们需要开辟多大的空间,此时需要旧数据以及新数据的总体数量。确定好之后在堆区开辟需要的内存大小,如有旧的数据吗,则需要将旧数据拷贝到新开辟的内存中,拷贝好之后则将新的数据添加到新的内存中。添加好之后将旧内存清空,更改新空间的指向,人数等信息。
样例代码如下:

void workerManager::Add_Emp()
{
	int Num = 0;//保存用户输入的数量
	cout << "需要添加的人数: " << endl;
	cin >> Num;
	if (Num > 0)
	{
		//添加
		//计算一下添加新的空间大小
		int newSize = this->m_EmpNum + Num; //新空间的大小等于原有空间大小加新的空间大小
		//开辟新空间
		worker ** newSpace = new worker *[newSize];
		//将原来空间下数据拷贝到新空间
		if (this->m_EmpNum  !=  NULL)
		{
			for (int i = 0; i < this->m_EmpNum; i++)
			{
				newSpace[i] = this->m_EmpArray[i];
			}
		}
		//批量添加新数据
		for (int i = 0; i < Num; i++)
		{
			int id; //职工编号
			string name; //职工姓名
			int dselect; //部门选择
			cout << "请输入第 " << i + 1 << " 个新职工的编号" << endl;
			cin >> id;
			cout << "请输入第 " << i + 1 << " 个新职工的姓名" << endl;
			cin >> name;
			cout << "请选择该职工的岗位: " <<  endl;
			cout << "1、普通职工" << endl;
			cout << "2、  经理  " << endl;
			cout << "3、  老板  " << endl;
			cin >> dselect;
			worker * w = NULL;
			switch (dselect)
			{
			//普通员工
			case 1:
				w = new Employee(id, name, 1);
				break;
			
			//经理
			case 2:
				w = new Manager(id, name, 2);
				break;

			//老板
			case 3:
				w = new Boss(id, name, 3);
				break;
			
			default:
				break;				
			}
			//将创建职工的指针保存到数组中
			newSpace[this->m_EmpNum + i] = w;
		}
		//释放原有的空间
		delete[]this->m_EmpArray;

		//更改新空间的指向
		this->m_EmpArray = newSpace;

		//更新职工人数
		this->m_EmpNum = newSize;

		//提示添加成功
		cout << "成功添加 " << Num << " 名职工" << endl;
	}
	else
	{
		cout << "输入有误" << endl;
	}
	system("pause");
	system("cls");
}

六、写文件操作

在项目操作过程中,我们需要将写入的数据进行永久的储存,来实现随时读取系统中数据的功能,这时就需要在我们员工管理系统中完成一个写文件的操作。实现起来很简单,只需要在workerManager头文件中先声明一个保存文件的类:

void save();

保存文件的实现很简单,我们在这里就不再赘述直接上代码:

//保存文件
void workerManager::save()
{
	ofstream ofs;
	ofs.open(FILEMANE, ios::out); //用输出的方式打开文件

	//将每个人的数据写入到文件中
	for (int i = 0; i < m_EmpNum; i++)
	{
		ofs << this->m_EmpArray[i]->m_ID << " "
			<< this->m_EmpArray[i]->m_name << " "
			<< this->m_EmpArray[i]->DeptId << endl;		
	}
	//关闭文件
	ofs.close();
}

七、读文件的操作

当我们启动系统时,我们需要通过读文件来获取我们之前输入的数据,具体的读入方法有三种情况:1、当文件不存在时,我们需要对文件进行一个创建,并且将系统中的人数以及开辟到内存中的大小设为0;2、当文件存在,但是文件中没有数据时,我们在系统运行时对系统进行一个初始化,即将系统中的人数以及开辟到内存中的大小设为0;3、文件存在,并且文件中有数据时,我们就需要对文件进行读取的操作了,下面我们在workerManager的析构函数中来实现情况1、2的代码:
在头文件中先要声明一个是否为空的标识符:

	//判断文件是否为空
	bool m_fileEEmpty;
	//1、文件不存在
	//流
	ifstream ifs;

	//打开文件
	ifs.open(FILEMANE, ios::in);

	//判断
	if (!ifs.is_open())
	{
		//初始化记录人数
		this->m_EmpNum = 0;
		//初始化数组指针
		this->m_EmpArray = NULL;
		//初始化文件是否为空
		this->m_fileEEmpty = true;
		ifs.close();
		return;
	}
	//2、文件存在,但是为空
	char ch;
	ifs >> ch;

	if (ifs.eof())
	{
		//初始化记录人数
		this->m_EmpNum = 0;
		//初始化数组指针
		this->m_EmpArray = NULL;
		//初始化文件是否为空
		this->m_fileEEmpty = true;
		//关闭文件
		ifs.close();
		return;
	}

涉及到情况三我们则需要对文件进行读取的操作,我们在workerManager的头文件中先声明一个读取文件的函数声明:

	//对职工人数计数
	int get_EmpNum();

	//初始化数组
	void init_Emp();

接下来我们在源文件中对以上两个函数进行具体的实现:

//对职工人数计数
int workerManager::get_EmpNum()
{
	ifstream ifs;
	ifs.open(FILEMANE, ios::in); //打开文件 读文件
	int id;
	string name;
	int did;
	int num = 0;
	while (ifs>>id && ifs>>name && ifs>>did)
	{
		//统计人数
		num++;
		
	}
	return num;
}

//初始化职工
void workerManager::init_Emp()
{
	int id;
	string name;
	int did;
	int index = 0;

	//打开文件
	ifstream ifs;
	ifs.open(FILEMANE, ios::in);

	while (ifs>>id && ifs>>name && ifs>>did)
	{
		worker * w = NULL;
		if (did == 1) //1、普通员工
		{
			w = new Employee(id, name, did);
		}

		else if (did == 2) //2、经理
		{
			w = new Manager(id, name, did);
		}

		else//3、老板
		{
			w = new Boss(id, name, did);
		}
		//存放到数组中
		this->m_EmpArray[index] = w;
		index++;
	}
	ifs.close();
}

八、显示职工信息

这节中我们实现系统中显示职工的信息,我们在显示之前需要判断系统存储文件是否存在,如果不存在,则显示系统文件为空,这里我们可以通过之前的标识符来进行判断。当文件存在,我们可以通过之前实现的showInfo()函数来实现,这节思路比较简单,就不在多说,直接上代码:

void workerManager::Show_Emp()
{
	//如果文件为空
	if (this->m_fileEEmpty)
	{
		cout << "系统中无数据" << endl;
	}

	//如果文件内有数据
	else
	{
		for (int i = 0; i < m_EmpNum; i++)
		{
			this->m_EmpArray[i]->showInfo();
		}
	}
	system("pause");
	system("cls");
}

九、删除职工信息

在删除职工信息,我们先要判断职工信息是否存在,我们首先要实现一下员工存在的标值位的函数实现,我们首先在头文件中写入一个如下的函数实现:

	//判断员工的id
	bool IsExist(int id);

在源文件中实现如上函数:

//判断职工信息是否存在
bool workerManager::IsExist(int id)
{
	bool index = false;
	ifstream ifs;
	ifs.open(FILEMANE, ios::in);
	for (int i = 0; i < m_EmpNum; i++)
	{
		if (this->m_EmpArray[i]->m_ID == id)
		{
			index = true;
			break;
		}
	}
	return index;
}

判断完成后我们就要实现一下删除职工的功能了首先在头文件中对函数进行一个声明:

	//删除职工信息
	void Del_Emp();

在源文件中对删除职工这一函数进行实现,在该段代码中,我们想要删除一个职工的信息,我们第一步要判断一下我们保存数据的文件是否存在,如不存在,则报异常,如果存在,则进行职工是否在数据库中的判断,如果不在数据库中,则报异常,如果在数据库中,则进行删除的操作,由于我们时通过数组来对员工进行读取以及保存的,我们可以先找到该员工所在的位置,再将该位置后面的数据覆盖到该位置中,依次循环,直到整个数组全部遍历完成,最后再更新一下系统中员工的人数。

//删除职工信息
void workerManager::Del_Emp()
{
	if (this->m_fileEEmpty)
	{
		cout << "系统为空" << endl;
	}
	else
	{
		//按照职工编号删除
		cout << "请输入想要删除职工的编号" << endl;
		int id;
		cin >> id;
		//说明该职工存在
		if (this->IsExist(id))
		{
			for (int i = 0; i < m_EmpNum - 1; i++)
			{
				if (this->m_EmpArray[i]->m_ID == id)
				{
					this->m_EmpArray[i] = this->m_EmpArray[i + 1];					
				}
			}
			this->m_EmpNum--;
			//同步更新到文件中
			this->save();
			cout << "删除成功!" << endl;
		}
		else
		{
			cout << "删除失败,没有找到该职工" << endl;
		}
		system("pause");
		system("cls");
	}
}

十、修改职工信息

在修改职工信息时,这与删除职工的功能类似,都是先查找保存数据的文件是否存在,检查要修改信息员工的信息是否存在,若不存在则抛出异常。我们先在头文件中先建立一个修改职工信息的声明:

	//修改职工信息
	void Mod_Emp();

在源文件中对该函数进行实现,实现过程中的修改信息操作流程如下:
1、先要找到要修改职工信息位置的索引
2、将对应位置的内存进行清空
3、创建一个包含新数据的对象
4、将创建好的对象放入到之前的数组位置种
具体的实现代码如下:

void workerManager::Mod_Emp()
{
	//判断文件是否存在,若不存在则报错
	if (this->m_fileEEmpty)
	{
		cout << "系统为空" << endl;
	}

	//若存在,则判断员工是否在系统中
	else
	{
		cout << "请输入要求该员工的编号" << endl;
		int id;
		cin >> id;
		int ret = this->IsExist(id);

		//判断员工是否在系统中
		if (ret != -1)
		{
			delete this->m_EmpArray[ret];
			int New_id = 0;
			string New_name = "";
			int New_Did = 0;

			cout << "请输入新的id" << endl;
			cin >> New_id;

			cout << "请输入新的名字" << endl;
			cin >> New_name;

			cout << "请输入新的岗位编号" << endl;
			cout << "1、普通职工" << endl;
			cout << "2、  经理  " << endl;
			cout << "3、  老板  " << endl;
			cin >> New_Did;

			worker * w = NULL;
			switch (New_Did)
			{
			case 1:
				w = new Employee(New_id, New_name, New_Did);
				break;

			case 2:
				w = new Manager(New_id, New_name, New_Did);
				break;

			case 3:
				w = new Boss(New_id, New_name, New_Did);
				break;
				
			default:
				cout << "岗位编号有误" << endl;
				break;
			}

			//更新到数组中
			this->m_EmpArray[ret] = w;

			cout << "修改完成!" << endl;
			system("pause");
			system("cls");
		}

		else
		{
			cout << "该员工没有在系统中!" << endl;
		}
	}
}

十一、按照编号对员工进行排序

该方法实现时也是与前几种的流程一致,先是判断文件是否存在,如果存在则进行一个冒泡排序法,在冒泡排序法时由用户选择按照升序还是降序进行排列,由于方法比较简单,这里就直接上源码:

//排序职工
void workerManager::Sort_Emp()
{
	if (
		this->m_fileEEmpty)
	{
		cout << "系统为空" << endl;
		system("pause");
		system("cls");
	}
	
	else
	{
		cout << "请选择排序方式" << endl;
		cout << "1、按照升序排列" << endl;
		cout << "2、按照降序排列" << endl;
		int select = 0;
		cin >> select;

		for (int i = 0; i < this->m_EmpNum; i++)
		{
			int minOrMax = i;
			for (int j = i+1; j < this->m_EmpNum; j++)
			{
				if (select == 1)
				{
					if (this->m_EmpArray[minOrMax]->m_ID > this->m_EmpArray[j]->m_ID)
					{
						minOrMax = j;
					}
				}

				//降序
				else
				{
					if (this->m_EmpArray[minOrMax]->m_ID < this->m_EmpArray[j]->m_ID)
					{
						minOrMax = j;
					}
				}
			}

			//判断最开始认定的最小值或者最大值,如果不是,则交换数据
			if (i != minOrMax)
			{
				worker * temp = this->m_EmpArray[i];
				this->m_EmpArray[i] = this->m_EmpArray[minOrMax];
				this->m_EmpArray[minOrMax] = temp;
			}
		}
		cout << "排序成功!排序后的结果为: " << endl;
		this->save(); //排序后的结果保存到文件中
		this->Show_Emp();//展示数据
	}
}

十二、清空系统数据

本节完成系统的最后一个功能,清空整个系统,这里用到一个新的文件打开方式:ofs.open(FILEMANE, ios::trunc);删除文件后重新新建一个文件
在这里我们对文件是否存在进行一个判断,如果存在,则对先文件进行一个清空,在对内存空间内的数据进行一个清空操作。清空后再对数组、人数进行一个初始化操作,相关代码如下:

//清空文件
void workerManager::clean_film()
{
		//判断文件是否存在
		if (!this->m_fileEEmpty)
		{
			cout << "确认要清空数据吗?" << endl;
			cout << "1、确认" << endl;
			cout << "2、返回" << endl;
			int select;
			cin >> select;

			//判断是否确认
			if (select == 1)
			{
				ofstream ofs;
				ofs.open(FILEMANE, ios::trunc); //删除文件后重新创建
				ofs.close();

				//删除堆区内的每一块数据
				if (this->m_EmpArray != NULL)
				{
					for (int i = 0; i < m_EmpNum; i++)
					{
						this->m_EmpArray[i] = NULL;
					}

					delete []this->m_EmpArray;
					this->m_fileEEmpty = NULL;
					this->m_EmpNum = 0;
					this->m_fileEEmpty = true;
				}
				cout << "清空完成" << endl;				
			}
		}		
		else
		{
			cout << "系统无可清空数据" << endl;
		}
		system("pause");
		system("cls");
}

至此整个系统的实现已经完毕!

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值