我的第一个C++千行项目——职工管理系统,宣布完结!


项目介绍

这是一个面向C++学习者的一个小项目,很适合已经学习完C++核心编程的朋友来练手,它可以帮助你把之前学习的技能融会贯通。

它的主要功能为:

  • 增加职工信息
  • 显示职工信息
  • 删除离职职工
  • 修改职工信息
  • 查找职工信息
  • 按照编号排序
  • 清空所有文档

了解了需求之后,用你的方式去实现它吧!

以下是我的实现:

头文件
boss.h
#pragma once
#include "worker.h"

class Boss :public Worker
{
public:
	Boss(int workerId, string name);

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

	//获取员工名字
	string getWorkerName();

	//获取岗位
	string getDepartmentName();

	//获取职责
	string getDepartmentDuty();
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
employee.h
#pragma once
#include "worker.h"

class Employee :public Worker
{
public:
	Employee(int workerId, string name);

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

	//获取员工名字
	string getWorkerName();

	//获取岗位
	string getDepartmentName();

	//获取职责
	string getDepartmentDuty();
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
manager.h
#pragma once
#include "worker.h"

class Manager:public Worker
{
public:
	Manager(int workerId, string name);

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

	//获取员工名字
	string getWorkerName();

	//获取岗位
	string getDepartmentName();

	//获取职责
	string getDepartmentDuty();
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
worker.h
#pragma once
#include <iostream>
using namespace std;
#include <string>

class Worker
{
public:
	//显示个人信息
	virtual void showInfo() = 0;

	//获取员工名字
	virtual string getWorkerName() = 0;

	//获取岗位
	virtual string getDepartmentName() = 0;

	//获取职责
	virtual string getDepartmentDuty() = 0;

//protected:
	//职工编号
	int workerId;
	//职工名字
	string workerName;
	//岗位
	string departmentName;
	//职责
	string departmentDuty;
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
workerManager.h
#pragma once
#include <iostream>
#include <fstream>
#include "worker.h"
using namespace std;
#define FILENAME "workerFile.txt"

//适配开始菜单的enum
enum
{
	EXIT,
	ADD,
	DISPALY,
	DELETE,
	MODIFY,
	SEEK,
	SORT,
	EMPTY
};

//适配员工职务选择的enum
enum
{
	BOSS = 1,
	MANAGER,
	EMPLOYEE
};

//适配查找员工方式的enum
enum
{
	RETURN,
	BYID,
	BYNAME
};

//启动程序
void Start();

//管理类:与用户的交互,调用职工管理系统内核
class WorkerManager
{
public:
	WorkerManager();

	void showMenu();

	void exitSystem();

	~WorkerManager();

	void AddWorker();

	void saveToFile();

	//从程序外的文件中,展示职工信息
	void showFromFile();

	//从程序内的数组中,展示职工信息
	void showFromArray();

	//更新指针位置
	void updateArray(Worker** newArray);

	//更新员工人数
	void updateWorkerNumber(int newWorkerNumber);

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

	//判断员工是否存在
	// 1.存在   ->  返回其下标
	// 2.不存在 ->  返回 -1
	int isExist(int id);

	//删除员工
	void deleteWorker();

	//修改员工信息
	void modifyWorkerInfo();

	void seekWorker();

	int getWorkerNumber();

	void sortWorkerById();

	bool existInfo();

	void emptyInfo();

private:
	bool fileEmpty;
	int fileWorkerNumber;
	int workerNumber;
	Worker** workerArray;
};
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
源文件
boss.cpp
#include "boss.h"

Boss::Boss(int workerId, string name)
{
	this->workerId = workerId;
	this->workerName = name;
	this->departmentName = "老板";
	this->departmentDuty = "为公司指明发展方向";//因为所有boss的职责都一样,所以我们这里直接写死
}

//显示个人所有信息
void Boss::showInfo()
{
	cout << "职工编号: " << this->workerId
		<< " \t职工姓名: " << this->workerName
		<< " \t岗位:" << this->getDepartmentName()
		<< " \t岗位职责:" << this->getDepartmentDuty() << endl;
}

//获取员工名字
string Boss::getWorkerName()
{
	return this->workerName;
}

//获取岗位
string Boss::getDepartmentName()
{
	return this->departmentName;
}

//获取职责
string Boss::getDepartmentDuty()
{
	return this->departmentDuty;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
employee.cpp
#include "employee.h"

Employee::Employee(int workerId, string name)
{
	this->workerId = workerId;
	this->workerName = name;
	this->departmentName = "基层员工";
	this->departmentDuty = "完成经理所分配的任务";//因为所有employee的职责都一样,所以我们这里直接写死
}

//显示个人所有信息
void Employee::showInfo()
{
	cout << "职工编号: " << this->workerId
		<< " \t职工姓名: " << this->workerName
		<< " \t岗位:" << this->getDepartmentName()
		<< " \t岗位职责:" << this->getDepartmentDuty() << endl;
}

//获取员工名字
string Employee::getWorkerName()
{
	return this->workerName;
}

//获取岗位
string Employee::getDepartmentName()
{
	return this->departmentName;
}

//获取职责
string Employee::getDepartmentDuty()
{
	return this->departmentDuty;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
manager.cpp
#include "manager.h"

Manager::Manager(int workerId, string name)
{
	this->workerId = workerId;
	this->workerName = name;
	this->departmentName = "经理";
	this->departmentDuty = "将任务合理分解给员工";//因为所有employee的职责都一样,所以我们这里直接写死
}

//显示个人所有信息
void Manager::showInfo()
{
	cout << "职工编号: " << this->workerId
		<< " \t职工姓名: " << this->workerName
		<< " \t岗位:" << this->getDepartmentName()
		<< " \t岗位职责:" << this->getDepartmentDuty() << endl;
}

//获取员工名字
string Manager::getWorkerName()
{
	return this->workerName;
}

//获取岗位
string Manager::getDepartmentName()
{
	return this->departmentName;
}

//获取职责
string Manager::getDepartmentDuty()
{
	return this->departmentDuty;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
workerManager.cpp
#include "workerManager.h"
#include "boss.h"
#include "employee.h"
#include "manager.h"

void Start()
{
	WorkerManager wm;
	int choice = 0;

	while (true)
	{
		wm.showMenu();
		cin >> choice;

		switch (choice)
		{
		case EXIT:
			wm.exitSystem();
			break;
		case ADD:
			wm.AddWorker();
			wm.saveToFile();
			break;
		case DISPALY:
			//wm.showFromFile();
			wm.showFromArray();
			break;
		case DELETE:
			wm.deleteWorker();
			break;
		case MODIFY:
			wm.modifyWorkerInfo();
			break;
		case SEEK:
			wm.seekWorker();
			break;
		case SORT:
			wm.sortWorkerById();
			break;
		case EMPTY:
			wm.emptyInfo();
			break;
		default:
			cout << "输入错误,请重新输入数字0~7:" << endl;
			cout << endl;
			break;
		}
	}
}

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;
}

WorkerManager::WorkerManager()
{
	//文件打开有3种情况,我们要为其做3种不同的构造函数:
	// 1.没有文件
	// 2.有文件,但内容为空(上次使用时,最后一步操作是“清空所有文档”)
	// 3.有文件,且里面有内容
	//

	ifstream ifs;
	ifs.open(FILENAME, ios::in);
	char fileEnd;

	//1.没有文件
	if (!ifs.is_open())
	{
		//cout << "文件不存在" << endl;
		
		this->fileEmpty = true;
		this->workerNumber = 0;
		this->workerArray = NULL;
		this->fileWorkerNumber = 0;

		ifs.close();
		return;
	}
	
	//2.有文件,但内容为空
	//
	//文件中最少会有一个字符——EOF,现在我们从文件读走一个字符
	//如果文件因此为空了,那么说明我们刚刚读走的就是EOF,也就是说,现在文档里什么都没有了
	//然后,我们利用ifs.eof()去判断文件是否为空,
	// 若为空,则得出结论:该文件内容为空
	ifs >> fileEnd;

	if (ifs.eof())
	{
		//cout << "文件为空" << endl;

		this->fileEmpty = true;
		this->workerNumber = 0;
		this->workerArray = NULL;
		this->fileWorkerNumber = 0;

		ifs.close();
		return;
	}

	//3.有文件,且里面有内容
	//
	//当代码走到这,说明前2种情况都没有发生,所以此处不需要进行if判断
	
	//a.先求出文件中有几条数据
	this->fileWorkerNumber = this->getWorkerNumber();
	//cout << this->fileWorkerNumber;

	//b.在数据中开辟等量的空间,以便后续将文件中的数据存放至数组中
	this->workerArray = new Worker * [this->fileWorkerNumber];
	
	//c.将文件中的数据存放至数组中
	initArray();

	this->fileEmpty = false;//更新文件是否为空的标志
	
	//d.更新数组中当前的数据数量
	this->workerNumber = this->fileWorkerNumber;

	//测试代码
	//for (int i = 0; i < this->workerNumber; i++)
	//{
	//	cout << this->workerArray[i]->workerId << " "
	//		<< this->workerArray[i]->workerName << " "
	//		<< this->workerArray[i]->departmentName << " "
	//		<< this->workerArray[i]->departmentDuty << endl;
	//}
}

WorkerManager::~WorkerManager()
{
	int i = 0;

	//我们这里是2级指针,所有实质上我们需要释放2次,才可以释放干净空间

	//1.释放数组中,每个元素(实质上是一级指针)所指向的空间
	if (this->workerArray != NULL)
	{
		for (i = 0; i < this->workerNumber; i++)
		{
			if (*(this->workerArray + i) != NULL)
			{
				delete* (this->workerArray + i);
				*(this->workerArray + i) = NULL;
			}
		}
	}

	//2.释放数组(释放数组中的每一个一级指针)
	delete[] this->workerArray;
	this->workerArray = NULL;
}

int WorkerManager::getWorkerNumber()
{
	ifstream ifs;
	int count = 0;
	string buf;

	ifs.open(FILENAME, ios::in);

	if (!ifs.is_open())
	{
		cout << "getWorkerNumber::打开文件失败!" << endl;
		return -1;
	}

	//getline函数,可以一次读一行
	//而我们一行只放了一个职工,所以行数 == 职工数
	while (getline(ifs, buf))
	{
		count++;
	}

	ifs.close();

	return count;
}

void WorkerManager::initArray()
{
	ifstream ifs;
	int workerId = 0;
	string workerName;
	string departmentDuty;
	string departmentName;

	int i = 0;
	Worker* newWorker = NULL;

	//打开文件,以便进行后续读取数据操作
	ifs.open(FILENAME, ios::in);
	if (!ifs.is_open())
	{
		cout << "initArray::文件打开失败" << endl;
	}

	//把文件中的数据拿出来,存放入程序的数组中
	while (ifs >> workerId && ifs >> workerName && ifs >> departmentName && ifs >> departmentDuty)
	{
		if (departmentName == "老板")
		{
			newWorker = new Boss(workerId, workerName);
		}
		else if (departmentName == "经理")
		{
			newWorker = new Manager(workerId, workerName);
		}
		else//普通员工
		{
			newWorker = new Employee(workerId, workerName);
		}

		*(this->workerArray + i) = newWorker;
		i++;
	}

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

void WorkerManager::updateArray(Worker** newArray)
{
	this->workerArray = newArray;
}

void WorkerManager::updateWorkerNumber(int newWorkerNumber)
{
	this->workerNumber = newWorkerNumber;
}

void WorkerManager::AddWorker()
{
	//有一个数据,分配一个空间

	int addNumber = 0;
	int newNumber = 0;
	Worker** newSpace = NULL;
	Worker* newWorker = NULL;

	int i = 0;
	int idCheck = 0;
	bool existSameId = false;

	string newName;
	int newDepartment = 0;
	int newWorkerId = 0;

	//录入需要的新空间数量
	while (true)
	{
		cout << "请输入增加职工的数量:" << endl;
		cin >> addNumber;

		//合法性判断:不可以是零或负数
		if (addNumber <= 0)
		{
			cout << "非法输入!请输入正整数" << endl;
		}
		else
		{
			break;
		}
	}
	

	newNumber = addNumber + this->workerNumber;

	//开始分配空间
	newSpace = new Worker * [newNumber];
	if (newSpace == NULL)
	{
		cout << "AddWorker::内存分配失败!" << endl;
		exit(1);
	}

	//开始往空间中存入数据
	//
	// 什么时候需要存数据?在有数据的时候。
	// 所以我们这里直接判断workerNumber是否有值
	//
	//先把之前的数据转移至新空间中
	if (this->workerNumber > 0)
	{
		for (i = 0; i < this->workerNumber; i++)
		{
			*(newSpace + i) = *(workerArray + i);
		}
	}

	//录入新数据
	for (i = 0; i < addNumber; i++)
	{
		cout << "请输入第" << i + 1 << "个新员工的姓名:" << endl;
		cin >> newName;

		//员工ID为主码,具有唯一性,所以我们必须检查是否有相同的ID录入
		//如果有,我们要求重新输入ID
		//
		//检查方法:遍历所有已存在的员工ID + 新增的员工ID(此ID还为拼接至程序的数组中),一一比对
		// (后续可以做先排序,再二分查找的优化,不过目前暂时不需要)
		cout << "请输入第" << i + 1 << "个新员工的工号:" << endl;
		do
		{
			existSameId = false;//每次进入循环时,重置标志为:不存在相同ID

			cin >> newWorkerId;

			//检查已存在的员工ID
			for (idCheck = 0; idCheck < this->workerNumber; idCheck++)
			{
				if ((*(this->workerArray + idCheck))->workerId == newWorkerId)
				{
					cout << "ID号" << newWorkerId << "已存在, 请重新输入员工ID:" << endl;
					existSameId = true;
					break;
				}
			}

			//检查本次新增的员工ID
			if (addNumber > 1)
			{
				for (idCheck = 0; idCheck < i; idCheck++)
				{
					if ((*(newSpace + idCheck))->workerId == newWorkerId)
					{
						cout << "ID号" << newWorkerId << "已存在, 请重新输入员工ID:" << endl;
						existSameId = true;
						break;
					}
				}
			}

		} while (existSameId);


		cout << "请输入第" << i + 1<< "个新员工的职务:" << endl;
		cout << "1.老板" << endl;
		cout << "2.经理" << endl;
		cout << "3.普通员工" << endl;
		cin >> newDepartment;

		switch (newDepartment)
		{
		case BOSS:
			newWorker = new Boss(newWorkerId, newName);
			break;
		case MANAGER:
			newWorker = new Manager(newWorkerId, newName);
			break;
		case EMPLOYEE:
			newWorker = new Employee(newWorkerId, newName);
			break;
		default:
			cout << "输入错误!请在职务选择处,输入数字 1~3 的闭区间:" << endl;
			i--;
			break;
		}
		*(newSpace + this->workerNumber + i)  = newWorker;
	}

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

	this->fileEmpty = false;//更新文件标志,表示文件不再为空

	//释放原来的空间
	//delete[] this->workerArray;
	for (i = 0; i < this->workerNumber; i++)
	{
		if (*(this->workerArray + i) != NULL)
		{
			delete *(this->workerArray + i);
			*(this->workerArray + i) = NULL;
		}
	}

	this->workerArray = newSpace;
	this->workerNumber = newNumber;

	system("pause");
	system("cls");
}
void WorkerManager::deleteWorker()
{
	//1.判断文件中是否有数据
	// 1.1 没有数据 -> 向屏幕输出报错信息(没有数据无法进行删除操作)
	// 1.2 有数据   -> 进行步骤2
	//2.要求用户输入ID
	// 2.1 没有此员工 -> 向屏幕输出报错信息:"没有该员工"
	// 2.2 有此员工   -> 在数组中删除此员工,并将数组的情况更新至文件中

	if (!this->existInfo())
	{
		return;
	}

	int i = 0;
	int id = 0;
	int index = 0;

	cout << "请输入要删除职工的ID:" << endl;
	cin >> id;

	index = this->isExist(id);

	if (index == -1)
	{
		cout << "没有ID为" << id << "的员工" << endl;
	}
	else
	{
		//删除数组中,下标为index的元素
		for (i = index; i < this->workerNumber - 1; i++)
		{
			//该数组中,本质上存放的是Worker类型的一级指针,所以可以直接赋值,而不需要重写等号运算符
			this->workerArray[i] = this->workerArray[i + 1];
		}

		//更新数组中的元素数量
		this->workerNumber--;

		//将数组中的情况,更新至文件中
		this->saveToFile();

		//向用户输出提示信息
		cout << "删除成功!" << endl;
	}
	
	system("pause");
	system("cls");
}


void WorkerManager::saveToFile()
{
	ofstream ofs;
	int i = 0;

	ofs.open(FILENAME, ios::out);

	for (i = 0; i < this->workerNumber; i++)
	{
		ofs << this->workerArray[i]->workerId << " "
			<< this->workerArray[i]->workerName << " "
			<< this->workerArray[i]->departmentName << "\t"
			<< this->workerArray[i]->departmentDuty << endl;
	}

	ofs.close();
}

void WorkerManager::showFromFile()
{
	ifstream ifs;
	string buf;

	//当我们尝试去打开一个文件时,有这几种情况:
	// 1.有这个文件   ->  打开成功
	// 2.没有这个文件 ->  打开失败
	//

	ifs.open(FILENAME, ios::in);

	if (!ifs.is_open())
	{
		cout << "showFromFile::文件打开失败" << endl;
		return;
	}

	//将文件的内容输出到屏幕上
	while (getline(ifs, buf))
	{
		cout << buf << endl;
	}

	ifs.close();

	system("pause");
	system("cls");
}

int WorkerManager::isExist(int id)
{
	//我们先不考虑id同名的情况,暂时认为每一个职工ID都是唯一的
	//在此前提的基础上,我们查找某一个ID的下标,则只需要遍历一遍数组即可

	int i = 0;
	
	for (i = 0; i < this->workerNumber; i++)
	{
		if (this->workerArray[i]->workerId == id)
		{
			//找到该员工,直接返回下标
			return i;
		}
	}

	//如果程序走到这儿,说明没有该员工。返回 -1
	return -1;
}

void WorkerManager::modifyWorkerInfo()
{
	//修改员工函数实现思想:
	// 1.合法性判断 -> 判断是否有该员工 || 文件里是否有数据  (这2种情况应该输出不同的提示)
	//		1.1 没有 ->  提示用户没有该用户,退出函数
	//		1.2 有   ->  进行步骤2
	// 2.将此员工delete掉
	// 3.把新数据存入该空间
	
	if (!this->existInfo())
	{
		return;
	}

	bool flag = true;
	int idWantModify = 0;
	int indexOfIdWantModify = 0;

	//员工的新信息
	Worker* newInfo = NULL;
	int newId = 0;
	string newName = "";
	int newDepartment = 0;

	cout << "请问你要修改的员工的ID是:" << endl;
	cin >> idWantModify;

	//判断是否存在此员工
	indexOfIdWantModify = isExist(idWantModify);

	if (indexOfIdWantModify == -1)
	{
		cout << "该用户不存在" << endl;

		system("pause");
		system("cls");

		return;
	}
	else
	{
		delete this->workerArray[indexOfIdWantModify];

		cout << "请输入原员工ID为" << idWantModify << "的新ID:" << endl;
		cin >> newId;

		cout << "请输入新名字:" << endl;
		cin >> newName;
		
		cout << "请输入新职务:" << endl;
		cout << "1.老板" << endl;
		cout << "2.经理" << endl;
		cout << "3.普通员工" << endl;
		cin >> newDepartment;

		while (flag)//在选择处添加一个循环,这样在错误输入时就可以重新输入
		{
			switch (newDepartment)
			{
			case BOSS:
				newInfo = new Boss(newId, newName);
				flag = false;
				break;
			case MANAGER:
				newInfo = new Manager(newId, newName);
				flag = false;
				break;
			case EMPLOYEE:
				newInfo = new Employee(newId, newName);
				flag = false;
				break;
			default:
				cout << "输入错误!请在职务选择处,输入数字 1~3 的闭区间:" << endl;
				break;
			}
		}

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

		
		*(this->workerArray + indexOfIdWantModify) = newInfo;//将新数据存入程序数组
		this->saveToFile();//更新文件信息

		system("pause");
		system("cls");
	}
}

void WorkerManager::seekWorker()
{
	//实现思想:
	// 1.合法性判断
	// 2.提供两种查找方式
	//		2.1 按ID查找(后续需完善程序,使其ID具有唯一性) -> 输出此ID的员工信息
	//		2.2 按姓名查找 -> 输出所有拥有该姓名的员工 (考虑到同名情况,我们应该遍历所有员工)
	//

	if (!this->existInfo())
	{
		return;
	}

	int seekBy = 0;
	int idWantSeek = 0;
	int i = 0;
	int indexIdWantSeek = 0;
	string nameWantSeek = "";
	bool ExistTheWorker = false;

	cout << "0.返回上一层" << endl;
	cout << "1.按员工ID查找" << endl;
	cout << "2.按员工姓名查找" << endl;

	while (true)
	{
		cin >> seekBy;

		//合法性判断
		if (seekBy != 1 && seekBy != 2 && seekBy != 0)
		{
			cout << "输入错误!请输入 1, 2 或 0:" << endl;
		}
		else
		{
			break;
		}
	}


	switch (seekBy)
	{
	case RETURN://退出修改函数
		cout << "按任意键返回上一菜单" << endl;
		break;
	case BYID:
	{
		//1.判断该员工是否存在
		//	1.1 存在 -> 输出该员工信息
		//	1.2 不存在 -> 询问用户是否继续查找
		//		1.2.1 继续 -> 循环switch语句
		//		1.2.2 不继续 -> 退出函数,返回主菜单

		cout << "请输入要查找的员工ID:" << endl;
		cin >> idWantSeek;

		indexIdWantSeek = this->isExist(idWantSeek);

		if (indexIdWantSeek != -1)
		{
			//this->workerArray[indexIdWantSeek]->showInfo();
			(*(this->workerArray + indexIdWantSeek))->showInfo();
		}
		else
		{
			cout << "没有该员工" << endl;

			//待实现:询问是否需要重新输入
			//.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
		}
	}
		break;
	case BYNAME:
	{
		cout << "请输入要查找的员工姓名:" << endl;		
		cin >> nameWantSeek;

		for (i = 0; i < this->workerNumber; i++)
		{
			if ((*(this->workerArray + i))->workerName == nameWantSeek)
			{
				(*(this->workerArray + i))->showInfo();	
				ExistTheWorker = true;
			}
		}

		//遍历结束,没有该员工
		if (!ExistTheWorker)
		{
			cout << "没有姓名为 " << nameWantSeek << " 的员工" << endl;
		}
	}
		break;
	default:
		break;
	}
	system("pause");
	system("cls");
}

void WorkerManager::sortWorkerById()
{
	//实现思想:利用冒泡排序继续
	//

	if (!this->existInfo())
	{
		return;
	}

	int sortStyle = 0;
	int i = 0;
	int j = 0;
	Worker* temp = NULL;
	bool swapped = false;

	cout << "请选择排序方式:" << endl;
	cout << "1.升序" << endl;
	cout << "2.降序" << endl;

	while (true)
	{
		//录入用户的选择
		cin >> sortStyle;

		//合法性判断
		if (cin.fail() || sortStyle != 1 && sortStyle != 2)
		{
			cout << "输入错误,请重新输入 1 或 2 :" << endl;

			// 清除错误标志
			cin.clear();

			// 忽略掉剩余的输入(直到换行符)
			cin.ignore(numeric_limits < streamsize >::max(), '\n');
		}
		else
		{
			for (i = 0; i < this->workerNumber; i++)
			{
				for (j = 0; j < this->workerNumber - i - 1; j++)
				{
					if (sortStyle == 1)
					{
						//升序 (从小到大)
						if ((*(this->workerArray + j))->workerId > (*(this->workerArray + j + 1))->workerId)
						{
							temp = *(this->workerArray + j);
							*(this->workerArray + j) = *(this->workerArray + j + 1);
							*(this->workerArray + j + 1) = temp;

							swapped = true;
						}
					}
					else
					{
						//降序 (从大到小)
						if ((*(this->workerArray + j))->workerId < (*(this->workerArray + j + 1))->workerId)
						{
							temp = *(this->workerArray + j);
							*(this->workerArray + j) = *(this->workerArray + j + 1);
							*(this->workerArray + j + 1) = temp;

							swapped = true;
						}
					}
				}

				//本次循环没有发生排序行为,即表示当前数据已经有序,提前退出循环
				if (!swapped)
				{
					break;
				}
			}

			//走到这里,说明输入正确,且排序结束
			//
			// 最后收尾工作:
			// 1.输出排序成功提示,
			// 2.更新至文档
			// 3.跳出循环,结束函数

			cout << "排序成功!" << endl;

			this->saveToFile();

			system("pause");
			system("cls");
			
			break;
		}
	}
}

void WorkerManager::emptyInfo()
{
	if (!this->existInfo())
	{
		return;
	}

	//实现思想:
	// 1. 清空文件信息:删除文件,并创建同名空文件
	// 2. 清空程序中数组信息:delete所有workerArrat中的数据

	int i = 0;
	int doubleConfirmation = 0;
	ofstream ofs;

	//清空功能比较危险,所以要求用户进行二次确认
	cout << "确认清空所有数据吗?" << endl;
	cout << "1.确认" << endl;
	cout << "2.返回主菜单" << endl;
	cin >> doubleConfirmation;

	//如果用户输入的是字符或其他任何非 1 的数据,都会直接返回主菜单
	if (doubleConfirmation == 1)
	{
		//清空文件

		//这个命令会判断文件是否存在,如果存在,它将删除此文件,并新创建一个同名空文件
		//换句话说,它可以实现清空文件内容的功能
		ofs.open(FILENAME, ios::trunc);
		ofs.close();

		//清空数组
		if (this->workerArray != NULL)
		{
			for (i = 0; i < this->workerNumber; i++)
			{
				if (this->workerArray + i != NULL)
				{
					delete* (this->workerArray + i);
					*(this->workerArray + i) = NULL;
				}

			}

			delete [] this->workerArray;
			this->workerArray = NULL;

			this->fileEmpty = true;
			this->workerNumber = 0;
			this->fileWorkerNumber = 0;
		}
		cout << "清空成功!" << endl;
	}
	system("pause");
	system("cls");
}

void WorkerManager::exitSystem()
{
	cout << "已经退出系统,欢迎下次使用" << endl;
	exit(0);
}

bool  WorkerManager::existInfo()
{
	//为什么要设置2个条件?
	//因为在这样一种情况时,fileEmpty为false,但实质上却已经没有数据了:打开系统后,利用删除功能,把用户一个个删完
	if (this->workerNumber == 0 || this->fileEmpty == true)
	{
		cout << "文件不存在或文件为空" << endl;

		system("pause");
		system("cls");

		return false;
	}
	return true;
}

void WorkerManager::showFromArray()
{
	// 1.判断数组是否有值
	//  1.1 若数组不存在 -> 输出报错信息:“文件不存在或文件为空”
	//	1.2 若数组有值 -> 输出数组信息

	int i = 0;

	if (!this->existInfo())
	{
		return;
	}
	else
	{
		for (i = 0; i < this->workerNumber; i++)
		{
			this->workerArray[i]->showInfo();
		}
	}
	system("pause");
	system("cls");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.
  • 340.
  • 341.
  • 342.
  • 343.
  • 344.
  • 345.
  • 346.
  • 347.
  • 348.
  • 349.
  • 350.
  • 351.
  • 352.
  • 353.
  • 354.
  • 355.
  • 356.
  • 357.
  • 358.
  • 359.
  • 360.
  • 361.
  • 362.
  • 363.
  • 364.
  • 365.
  • 366.
  • 367.
  • 368.
  • 369.
  • 370.
  • 371.
  • 372.
  • 373.
  • 374.
  • 375.
  • 376.
  • 377.
  • 378.
  • 379.
  • 380.
  • 381.
  • 382.
  • 383.
  • 384.
  • 385.
  • 386.
  • 387.
  • 388.
  • 389.
  • 390.
  • 391.
  • 392.
  • 393.
  • 394.
  • 395.
  • 396.
  • 397.
  • 398.
  • 399.
  • 400.
  • 401.
  • 402.
  • 403.
  • 404.
  • 405.
  • 406.
  • 407.
  • 408.
  • 409.
  • 410.
  • 411.
  • 412.
  • 413.
  • 414.
  • 415.
  • 416.
  • 417.
  • 418.
  • 419.
  • 420.
  • 421.
  • 422.
  • 423.
  • 424.
  • 425.
  • 426.
  • 427.
  • 428.
  • 429.
  • 430.
  • 431.
  • 432.
  • 433.
  • 434.
  • 435.
  • 436.
  • 437.
  • 438.
  • 439.
  • 440.
  • 441.
  • 442.
  • 443.
  • 444.
  • 445.
  • 446.
  • 447.
  • 448.
  • 449.
  • 450.
  • 451.
  • 452.
  • 453.
  • 454.
  • 455.
  • 456.
  • 457.
  • 458.
  • 459.
  • 460.
  • 461.
  • 462.
  • 463.
  • 464.
  • 465.
  • 466.
  • 467.
  • 468.
  • 469.
  • 470.
  • 471.
  • 472.
  • 473.
  • 474.
  • 475.
  • 476.
  • 477.
  • 478.
  • 479.
  • 480.
  • 481.
  • 482.
  • 483.
  • 484.
  • 485.
  • 486.
  • 487.
  • 488.
  • 489.
  • 490.
  • 491.
  • 492.
  • 493.
  • 494.
  • 495.
  • 496.
  • 497.
  • 498.
  • 499.
  • 500.
  • 501.
  • 502.
  • 503.
  • 504.
  • 505.
  • 506.
  • 507.
  • 508.
  • 509.
  • 510.
  • 511.
  • 512.
  • 513.
  • 514.
  • 515.
  • 516.
  • 517.
  • 518.
  • 519.
  • 520.
  • 521.
  • 522.
  • 523.
  • 524.
  • 525.
  • 526.
  • 527.
  • 528.
  • 529.
  • 530.
  • 531.
  • 532.
  • 533.
  • 534.
  • 535.
  • 536.
  • 537.
  • 538.
  • 539.
  • 540.
  • 541.
  • 542.
  • 543.
  • 544.
  • 545.
  • 546.
  • 547.
  • 548.
  • 549.
  • 550.
  • 551.
  • 552.
  • 553.
  • 554.
  • 555.
  • 556.
  • 557.
  • 558.
  • 559.
  • 560.
  • 561.
  • 562.
  • 563.
  • 564.
  • 565.
  • 566.
  • 567.
  • 568.
  • 569.
  • 570.
  • 571.
  • 572.
  • 573.
  • 574.
  • 575.
  • 576.
  • 577.
  • 578.
  • 579.
  • 580.
  • 581.
  • 582.
  • 583.
  • 584.
  • 585.
  • 586.
  • 587.
  • 588.
  • 589.
  • 590.
  • 591.
  • 592.
  • 593.
  • 594.
  • 595.
  • 596.
  • 597.
  • 598.
  • 599.
  • 600.
  • 601.
  • 602.
  • 603.
  • 604.
  • 605.
  • 606.
  • 607.
  • 608.
  • 609.
  • 610.
  • 611.
  • 612.
  • 613.
  • 614.
  • 615.
  • 616.
  • 617.
  • 618.
  • 619.
  • 620.
  • 621.
  • 622.
  • 623.
  • 624.
  • 625.
  • 626.
  • 627.
  • 628.
  • 629.
  • 630.
  • 631.
  • 632.
  • 633.
  • 634.
  • 635.
  • 636.
  • 637.
  • 638.
  • 639.
  • 640.
  • 641.
  • 642.
  • 643.
  • 644.
  • 645.
  • 646.
  • 647.
  • 648.
  • 649.
  • 650.
  • 651.
  • 652.
  • 653.
  • 654.
  • 655.
  • 656.
  • 657.
  • 658.
  • 659.
  • 660.
  • 661.
  • 662.
  • 663.
  • 664.
  • 665.
  • 666.
  • 667.
  • 668.
  • 669.
  • 670.
  • 671.
  • 672.
  • 673.
  • 674.
  • 675.
  • 676.
  • 677.
  • 678.
  • 679.
  • 680.
  • 681.
  • 682.
  • 683.
  • 684.
  • 685.
  • 686.
  • 687.
  • 688.
  • 689.
  • 690.
  • 691.
  • 692.
  • 693.
  • 694.
  • 695.
  • 696.
  • 697.
  • 698.
  • 699.
  • 700.
  • 701.
  • 702.
  • 703.
  • 704.
  • 705.
  • 706.
  • 707.
  • 708.
  • 709.
  • 710.
  • 711.
  • 712.
  • 713.
  • 714.
  • 715.
  • 716.
  • 717.
  • 718.
  • 719.
  • 720.
  • 721.
  • 722.
  • 723.
  • 724.
  • 725.
  • 726.
  • 727.
  • 728.
  • 729.
  • 730.
  • 731.
  • 732.
  • 733.
  • 734.
  • 735.
  • 736.
  • 737.
  • 738.
  • 739.
  • 740.
  • 741.
  • 742.
  • 743.
  • 744.
  • 745.
  • 746.
  • 747.
  • 748.
  • 749.
  • 750.
  • 751.
  • 752.
  • 753.
  • 754.
  • 755.
  • 756.
  • 757.
  • 758.
  • 759.
  • 760.
  • 761.
  • 762.
  • 763.
  • 764.
  • 765.
  • 766.
  • 767.
  • 768.
  • 769.
  • 770.
  • 771.
  • 772.
  • 773.
  • 774.
  • 775.
  • 776.
  • 777.
  • 778.
  • 779.
  • 780.
  • 781.
  • 782.
  • 783.
  • 784.
  • 785.
  • 786.
  • 787.
  • 788.
  • 789.
  • 790.
  • 791.
  • 792.
  • 793.
  • 794.
  • 795.
  • 796.
  • 797.
  • 798.
  • 799.
  • 800.
  • 801.
  • 802.
  • 803.
  • 804.
  • 805.
  • 806.
  • 807.
  • 808.
  • 809.
  • 810.
  • 811.
  • 812.
  • 813.
  • 814.
  • 815.
  • 816.
  • 817.
  • 818.
  • 819.
  • 820.
  • 821.
  • 822.
  • 823.
  • 824.
  • 825.
  • 826.
  • 827.
  • 828.
  • 829.
  • 830.
  • 831.
  • 832.
  • 833.
  • 834.
  • 835.
  • 836.
  • 837.
  • 838.
  • 839.
  • 840.
  • 841.
  • 842.
  • 843.
  • 844.
  • 845.
  • 846.
  • 847.
  • 848.
  • 849.
  • 850.
  • 851.
  • 852.
  • 853.
  • 854.
  • 855.
  • 856.
  • 857.
  • 858.
  • 859.
  • 860.
  • 861.
  • 862.
  • 863.
  • 864.
  • 865.
  • 866.
  • 867.
  • 868.
  • 869.
  • 870.
  • 871.
  • 872.
  • 873.
  • 874.
  • 875.
  • 876.
  • 877.
  • 878.
  • 879.
  • 880.
  • 881.
  • 882.
  • 883.
  • 884.
  • 885.
  • 886.
  • 887.
  • 888.
  • 889.
  • 890.
  • 891.
  • 892.
  • 893.
  • 894.
  • 895.
  • 896.
  • 897.
  • 898.
  • 899.
  • 900.
mian.cpp
#include "workerManager.h"
#include "worker.h"
#include "employee.h"
#include "boss.h"
#include "manager.h"

int main()
{
	Start();
  
	return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
写在最后

在每天写bug,debug的过程中,我感受到了无穷的乐趣。

快乐尽在coding中,你也一起爽起来吧!

另外,如果你还有好的项目,欢迎评论或私信,让我也参与进来。