c/c++入门教程 - 3 职工管理系统 完整代码

目录

3 职工管理系统

3.1 管理系统需求

3.2 代码

勘误


3 职工管理系统

编写示例:基于多态的企业职工系统。

 

3.1 管理系统需求

职工管理系统可以用来管理公司内所有员工的信息。

本教程主要利用C++来实现一个基于多态的职工管理系统。

 

公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责

普通员工职责:完成经理交给的任务。

经理职责:完成老板交给的任务,并下发任务给员工。

老板职责:管理公司所有事务。

 

管理系统中需要实现的功能如下:

  • 退出管理程序:退出当前管理系统
  • 增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
  • 显示职工信息:显示公司内部所有职工的信息
  • 删除离职职工:按照编号删除指定的职工
  • 修改职工信息:按照编号修改职工个人信息
  • 查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息。
  • 按照编号排序:按照职工编号,进行排序,排序规则由用户指定
  • 清空所有文档:清空文件中记录的所有职工信息(清空前需要再次确认,防止误删)

 

3.2 代码

较大。

 

职工管理系统.cpp

#include <iostream>
using namespace std;
#include <string>
#include "workerManager.h"
#include "worker.h"

int main()
{
	int choice = 0;	// 存储用户选项
	WorkerManager wm;

	/*// 测试代码
	// 在堆区的写法,多态的使用
	//Worker* worker = new Employee(1, "张三", 1);

	// 在栈区的写法,多态的使用
	Employee e1 (1, "张三", 1);
	Worker* worker = &e1;

	Manager m1(2, "李四", 2);
	worker = &m1;

	Boss b1(3, "王五", 3);
	worker = &b1;

	// 显示职工信息
	worker->showInfo();*/

	while (true)
	{
		// 显示菜单
		wm.ShowMenu();

		// 获取用户输入的功能码
		cout << "请输入您选择的功能:" << endl;
		cin >> choice;

		/*int* a = new int;
		*a = 2;
		a[0] = 2;//可以这么用但不建议
		int* b = new int[5];
		*(b + 1) = 10;
		b[2] = 10;

		int** c = new int*[5];
		*c = a;
		c[2] = b;*/

		switch (choice)
		{
		case 0:	// 退出系统
			wm.ExitSystem();
			break;
		case 1:	// 添加职工
			wm.Add_Emp();
			break;
		case 2:	// 显示职工
			wm.show_Emp();
			break;
		case 3:	// 删除职工
			wm.Del_Emp();
			break;
		case 4:	// 修改职工
			wm.Mod_Emp();
			break;
		case 5:	// 查找职工
			wm.Find_Emp();
			break;
		case 6:	// 排序职工
			wm.Sort_Emp();
			break;
		case 7:	// 清空文件
			wm.Clean_File();
			break;
		default:
			system("cls");	// clear screen 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

 

worker.cpp

#include "worker.h"

// 构造函数,初始化员工信息
Employee::Employee(int id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

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

// 获取岗位名称
string Employee::getDeptName()
{
	return string("员工");//类型转换为string
}






// 构造函数
Manager::Manager(int id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}

// 显示个人信息
void Manager::showInfo()
{
	cout << "经理编号: " << this->m_Id
		<< "\t经理姓名: " << this->m_Name
		<< "\t岗位: " << this->getDeptName()
		<< "\t岗位职责: 完成老板交给的任务,并且下发任务给员工" << endl;
}

// 获取岗位名称
string Manager::getDeptName()
{
	return string("经理");//类型转换为string
}





// 构造函数
Boss::Boss(int id, string name, int dId)
{
	this->m_Id = id;
	this->m_Name = name;
	this->m_DeptId = dId;
}
// 显示个人信息
void Boss::showInfo()
{
	cout << "老板编号: " << this->m_Id
		<< "\t老板姓名: " << this->m_Name
		<< "\t岗位: " << this->getDeptName()
		<< "\t岗位职责: 管理公司所有事务" << endl;
}
// 获取岗位名称
string Boss::getDeptName()
{
	return string("总裁");//类型转换为string
}

 

worker.h

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

// 职工抽象类
class Worker
{
public:

	// 显示个人信息
	virtual void showInfo() = 0;
	// 获取岗位名称
	virtual string getDeptName() = 0;

	// 职工编号
	int m_Id;
	// 职工姓名
	string m_Name;
	// 部门编号
	int m_DeptId;
};

// 雇员类
class Employee :public Worker
{
public:

	// 构造函数,初始化员工信息
	Employee(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取岗位名称
	virtual string getDeptName();
};

// 经理类
class Manager :public Worker
{
public:

	// 构造函数
	Manager(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取岗位名称
	virtual string getDeptName();
};

// 老板类
class Boss:public Worker
{
public:

	// 构造函数
	Boss(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取岗位名称
	virtual string getDeptName();
};

 

workerManager.cpp

#include "workerManager.h"

// 构造函数
WorkerManager::WorkerManager()
{
	// 判断存储文件状态

	ifstream ifs;
	ifs.open(FILENAME, ios::in); // 读文件

	// 1、文件不存在的情况
	if (!ifs.is_open())
	{
		cout << "文件不存在" << endl;
		// 初始化属性
		// 初始化人数
		this->m_EmpNum = 0;
		// 初始化数组指针
		this->m_EmpArray = NULL;
		// 初始化文件是否为空
		this->m_FileIsEmpty = true;

		ifs.close();
		return;
	}

	// 2、文件存在,数据为空,没有记录任何员工信息
	// 判断文件是否为空
	char ch;
	ifs >> ch;
	if (ifs.eof()) // end of file,文件结尾
	{
		cout << "文件为空" << endl;
		// 初始化属性
		// 初始化人数
		this->m_EmpNum = 0;
		// 初始化数组指针
		this->m_EmpArray = NULL;
		// 初始化文件是否为空
		this->m_FileIsEmpty = true;

		ifs.close();
		return;
	}

	// 3、文件存在,并且已有员工消息
	int num = this->get_EmpNum();
	// 测试代码
	/*cout << "职工人数为:" << num << endl;*/
	this->m_EmpNum = num;

	// 申请空间,存放各个员工指针的数组
	this->m_EmpArray = new Worker * [this->m_EmpNum];
	// 将文件中的职工数据,存到数组中
	this->init_Emp();

	/*// 测试代码,对员工信息打印输出
	for (int i = 0; i < this->m_EmpNum; i++)
	{
		cout << "职工编号: " << this->m_EmpArray[i]->m_Id
			<< "\t职工姓名: " << this->m_EmpArray[i]->m_Name
			<< "\t部门编号: " << this->m_EmpArray[i]->m_DeptId
			<< "\t岗位: " << this->m_EmpArray[i]->getDeptName() << endl;
	}*/
	
}

// 展示菜单
void WorkerManager::ShowMenu()
{
	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;
	cout << endl;
}

// 退出系统
void WorkerManager::ExitSystem()
{
	cout << "欢迎下次使用" << endl;
	system("pause");
	exit(0);	// 退出应用
}

// 添加职工
void WorkerManager::Add_Emp()
{
	cout << "请输入添加职工的数量:" << endl;
	int addNum = 0; // 保存用户的输入数量
	cin >> addNum;

	if (addNum > 0)
	{
		// 计算添加新空间的大小
		int newSize = this->m_EmpNum + addNum; // 新空间人数 = 原来记录的人数 + 新增人数

		// 开辟新空间
		Worker** newSpace = new Worker * [newSize];

		// 将原来空间下的数据,拷贝到新空间下
		if (this->m_EmpArray != NULL) // 判断原数组是否为空
		{
			for (int i = 0; i < this->m_EmpNum; i++)
			{
				newSpace[i] = this->m_EmpArray[i];
			}
		}

		// 批量添加新数据
		for (int i=0; i<addNum; 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* worker = NULL;
			switch (dSelect)
			{
			case 1:
				worker = new Employee(id, name, 1);
				break;
			case 2:
				worker = new Manager(id, name, 1);
				break;
			case 3:
				worker = new Boss(id, name, 1);
				break;
			default:
				break;
			}
			// 将创建职工的指针,保存在数组中
			newSpace[this->m_EmpNum + i] = worker;
		}

		// 释放原有空间
		delete[] this->m_EmpArray;

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

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

		// 提示添加成功
		cout << "成功添加" << addNum << "名新职工!" << endl;

		// 保存员工信息为文件
		this->save();

		// 更新职工不为空标志
		this->m_FileIsEmpty = false;
	}
	else
	{
		cout << "输入数据有误" << endl;
	}

	// 按任意键清屏,回到上级目录
	system("pause");
	system("cls");
}

// 保存文件
void WorkerManager::save()
{
	ofstream ofs;
	ofs.open(FILENAME, ios::out);	// 用写文件的方式打开文件
	if (!ofs.is_open())
	{
		cout << "文件打开失败" << endl;
		return;	// 失败结束
	}

	// 将每个人数据写入到文件中
	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;
	}

	// 关闭文件
	ofs.close();
}

// 统计文件中人数
int WorkerManager::get_EmpNum()
{
	ifstream ifs;
	ifs.open(FILENAME, 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()
{
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	int id;
	string name;
	int dId;

	int index = 0;
	while (ifs >> id && ifs >> name && ifs >> dId)
	{
		Worker* worker = NULL;

		if (dId == 1) // 普通职工
		{
			worker = new Employee(id, name, dId);
		}
		else if (dId == 2) // 经理
		{
			worker = new Manager(id, name, dId);
		}
		else // 老板
		{
			worker = new Boss(id, name, dId);
		}

		this->m_EmpArray[index] = worker;
		index++;
	}
	// 关闭文件
	ifs.close();
}

// 显示员工
void WorkerManager::show_Emp()
{
	// 判断文件是否为空
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		for (int i=0; i<this->m_EmpNum; i++)
		{
			// 利用多态调用程序接口
			this->m_EmpArray[i]->showInfo();
		}
	}
	// 按任意键清屏
	system("pause");
	system("cls");
}

// 判断员工是否存在。若存在,返回数组中的位置,不存在返回-1
int WorkerManager::isExist(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;
}

// 删除职工
void WorkerManager::Del_Emp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入删除的员工编号:" << endl;
		int id = 0;
		cin >> id;

		int index = this->isExist(id);
		if (index != -1) // 说明职工存在,并且要删除index位置数组上的职工
		{
			// 释放删除掉的员工的内存
			delete this->m_EmpArray[index];
			// 数组前移
			for (int i = index; i < this->m_EmpNum; i++)
			{
				this->m_EmpArray[i] = this->m_EmpArray[i+1];
			}
			this->m_EmpNum--; // 更新数组中记录人员个数
			// 数据同步更新到文件中
			this->save();
			cout << "删除成功!" << endl;
		}
		else
		{
			cout << "删除失败,未找到职工" << endl;
		}
	}

	// 按任意键清屏
	system("pause");
	system("cls");
}

// 修改职工
void WorkerManager::Mod_Emp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入修改的员工编号:" << endl;
		int id = 0;
		cin >> id;

		int index = this->isExist(id);
		if (index != -1)
		{
			// 查找到职工编号
			// 释放删除掉的员工的内存
			delete this->m_EmpArray[index];

			// 将新信息录入
			int newId = 0;
			string newName = "";
			int newdId = 0;

			cout << "查找:" << id << "号职工,请输入新职工编号:" << endl;
			cin >> newId;
			cout << "请输入姓名" << endl;
			cin >> newName;
			cout << "请输入岗位:" << endl;
			cout << "1、普通职工" << endl;
			cout << "2、经理" << endl;
			cout << "3、老板" << endl;
			cin >> newdId;

			Worker* worker = NULL;
			switch (newdId)
			{
			case 1:
				worker = new Employee(newId, newName, newdId);
				break;
			case 2:
				worker = new Manager(newId, newName, newdId);
				break;
			case 3:
				worker = new Boss(newId, newName, newdId);
				break;
			default:
				break;
			}

			// 更新数据到数组中
			this->m_EmpArray[index] = worker;

			cout << "修改成功!" << endl;

			// 数据保存到文件中
			this->save();
		}
		else
		{
			cout << "修改失败,查无此人" << endl;
		}
	}

	// 按任意键清屏
	system("pause");
	system("cls");
}

// 查找职工
// 提供两种查找方式,一种按照职工编号,一种按照职工姓名。编号不能重名,姓名可以重名
void WorkerManager::Find_Emp()
{
	if (this->m_FileIsEmpty)
	{
		cout << "文件不存在或记录为空!" << endl;
	}
	else
	{
		cout << "请输入查找的方式:" << endl;
		cout << "1、按照职工编号查找" << endl;
		cout << "2、按照职工姓名查找" << endl;

		int select = 0;
		cin >> select;

		if (select == 1)
		{
			// 按编号查找
			int id;
			cout << "请输入员工编号:" << endl;
			cin >> id;

			int index = isExist(id);
			if (index != -1)
			{
				// 找到职工
				cout << "查找成功!该职工信息如下:" << endl;
				this->m_EmpArray[index]->showInfo();
			}
			else
			{
				cout << "查找失败!查无此人" << endl;
			}
		}
		else if (select == 2)
		{
			// 按姓名查找
			string name;
			cout << "请输入查找的姓名:" << endl;
			cin >> name;

			bool flag = false; // 查找到标志:0-未找到;1-查找到
							   // 没有用break去计i溢出的方法,是为了在名字重复时也能全部显示
			for (int i=0; i<m_EmpNum; i++)
			{
				if (m_EmpArray[i]->m_Name == name)
				{
					cout << "查找成功,职工编号为:"
						<< this->m_EmpArray[i]->m_Id
						<< " ,信息如下:" << endl;

					this->m_EmpArray[i]->showInfo();
					flag = true;
				}
			}
			if (!flag)
			{
				cout << "查找失败!查无此人" << endl;
			}
		}
		else
		{
			// 输入错误
			cout << "输入选项有误!" << endl;
		}
	}

	// 按任意键清屏
	system("pause");
	system("cls");
}

// 排序,选择排序
void WorkerManager::Sort_Emp()
{
	if (this->m_FileIsEmpty)
	{
		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<m_EmpNum; i++)
		{
			int minOrMax = i;
			for (int j = i + 1; j < m_EmpNum; j++)
			{
				if (select == 1) // 升序
				{
					if (m_EmpArray[minOrMax]->m_Id > m_EmpArray[j]->m_Id)
					{
						minOrMax = j;
					}
				}
				else // 降序
				{
					if (m_EmpArray[minOrMax]->m_Id < m_EmpArray[j]->m_Id)
					{
						minOrMax = j;
					}
				}
			}

			if (i != minOrMax)
			{
				Worker* temp = m_EmpArray[i];
				m_EmpArray[i] = m_EmpArray[minOrMax];
				m_EmpArray[minOrMax] = temp;
			}
		}

		cout << "排序成功,排序后结果为:" << endl;
		this->save();
		this->show_Emp();
	}

}

// 清空文件
void WorkerManager::Clean_File()
{
	cout << "确认清空?";
	cout << "1、确认" << endl;
	cout << "2、返回" << endl;

	int select = 0;
	cin >> select;

	if (select == 1)
	{
		// 打开模式 ios::trunc 如果文件存在,删除文件并重新创建
		ofstream ofs(FILENAME, ios::trunc);
		ofs.close();

		if (this->m_EmpArray != NULL)
		{
			// 删除堆区的每个职工对象
			for (int i=0; i<m_EmpNum; i++)
			{
				if (this->m_EmpArray[i] != NULL)
				{
					delete this->m_EmpArray[i];
				}
			}
			// 删除堆区数组指针
			this->m_EmpNum = 0;
			delete[] this->m_EmpArray;
			this->m_EmpArray = NULL;
			this->m_FileIsEmpty = true;
		}
		cout << "清空成功!" << endl;
	}

	// 按任意键清屏
	system("pause");
	system("cls");
}


// 析构函数
WorkerManager::~WorkerManager()
{
	if (this->m_EmpArray != NULL)
	{
		delete[] this->m_EmpArray;
		this->m_EmpArray = NULL;
	}
	//
	// 因为有了 更改新空间指向,所以释放 this->m_EmpArray 等于释放 newSpace。
}

 

workerManager.h

#pragma once
#include <iostream>
#include "worker.h"
#include <fstream>
using namespace std;

#define FILENAME "empFile.txt"

class WorkerManager
{
public:

	// 构造函数
	WorkerManager();

	// 展示菜单
	void ShowMenu();

	// 退出系统
	void ExitSystem();

	// 记录职工人数
	int m_EmpNum;

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

	// 添加职工
	void Add_Emp();

	// 保存文件
	void save();

	// 判断文件释放为空 的标志
	bool m_FileIsEmpty;

	// 统计文件中的人数
	int get_EmpNum();

	// 初始化员工,从文件中读取所有员工
	void init_Emp();

	// 显示员工
	void show_Emp();

	// 判断员工是否存在。若存在,返回数组中的位置,不存在返回-1
	int isExist(int id);

	// 删除职工
	void Del_Emp();

	// 修改职工
	void Mod_Emp();

	// 查找职工
	void Find_Emp();

	// 排序,选择排序
	void Sort_Emp();

	// 清空文件
	void Clean_File();

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

 

 

勘误

写文件的过程,记得加上

if (!ofs.is_open())
{
	cout << "文件打开失败" << endl;
	return;	// 失败结束
}

不然第一次创建会是空文件,而且会报错。

 

删除员工,记得释放删除掉的内存。

 

选择排序算法,事后好好读一下。

  • 9
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值