职工管理系统
1、管理系统需求
职工管理系统可以用来管理公司内所有员工的信息
本教程主要利用C++来实现一个基于多态的职工管理系统
公司中职工分为三类:普通员工、经理、老板,显示信息时,需要显示职工编号、职工姓名、职工岗位、以及职责
普通员工职责:完成经理交给的任务
经理职责:完成老板交给的任务,并下发任务给员工
老板职责:管理公司所有事务
管理系统中需要实现的功能如下:
- 退出管理程序:退出当前管理系统
- 增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
- 显示职工信息:显示公司内部所有职工的信息
- 删除离职职工:按照编号删除指定的职工
- 修改职工信息:按照编号修改职工个人信息
- 查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息
- 按照编号排序:按照职工编号,进行排序,排序规则由用户指定
- 清空所有文档:清空文件中记录的所有职工信息 (清空前需要再次确认,防止误删)
系统界面效果图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yybfg02Q-1675440469277)(null)]
需根据用户不同的选择,完成不同的功能!
2、创建项目
创建项目步骤如下:
- 创建新项目
- 添加文件
2.1 创建项目
略
2.2 添加文件
略
3、创建管理类
管理类负责的内容如下:
- 与用户的沟通菜单界面
- 对职工增删改查的操作
- 与文件的读写交互
3.1创建文件
在头文件和源文件的文件夹下分别创建workerManager.h 和 workerManager.cpp文件
3.2 头文件实现
在workerManager.h中设计管理类
此处的workerManager类函数为分文件类外定义,相关知识点可见:类外实现
C++头文件相关知识点:ifndef使用
代码如下:
#ifndef WorkerManager_H //防止头文件的重复包含和编译 一般名字设置为文件名大写加上H,C++ 5th推荐加下划线6th没有
#define WorkerManager_H
//职工类
class WorkerManager {
public:
//构造函数
WorkerManager();
//析构函数
~WorkerManager();
};
#endif
//VS默认#pragma once但是使用了支持更加广泛的ifndef
3.3 源文件实现
在workerManager.cpp中将构造和析构函数空实现补全
#include"workerManager.h"
#include<iostream>
WorkerManager::WorkerManager() {
}
WorkerManager::~WorkerManager() {
}
至此职工管理类以创建完毕
4、菜单功能
功能描述:与用户的沟通界面
4.1 添加成员函数
在管理类workerManager.h中添加成员函数 void Show_Menu();
4.2 菜单功能实现
在管理类workerManager.cpp中实现 Show_Menu()函数
#include"workerManager.h"
#include<iostream>
//using namespace std;//尽量少使用,如果使用放在所有include之后
//using std::cout;
WorkerManager::WorkerManager() {
}
WorkerManager::~WorkerManager() {
}
//显示菜单
void WorkerManager::showMenu() {
std::cout << "********************************************" << std::endl;
std::cout << "********* 欢迎使用职工管理系统! **********" << std::endl;
std::cout << "************* 0.退出管理程序 *************" << std::endl;
std::cout << "************* 1.增加职工信息 *************" << std::endl;
std::cout << "************* 2.显示职工信息 *************" << std::endl;
std::cout << "************* 3.删除离职职工 *************" << std::endl;
std::cout << "************* 4.修改职工信息 *************" << std::endl;
std::cout << "************* 5.查找职工信息 *************" << std::endl;
std::cout << "************* 6.按照编号排序 *************" << std::endl;
std::cout << "************* 7.清空所有文档 *************" << std::endl;
std::cout << "********************************************" << std::endl;
std::cout << std::endl;
}
4.3 测试菜单功能
在职工管理系统.cpp中测试菜单功能
代码:
#include<iostream>
#include "workerManager.h"
int main() {
WorkerManager wm;
wm.Show_Menu();
system("pause");
return 0;
}
5、退出功能
5.1 提供功能接口
在main函数中提供分支选择,提供每个功能接口
代码:
#include<iostream>
#include "workerManager.h"
int main() {
WorkerManager wm;
int choice = 0;//功能选择,默认为0
while (true) {//菜单循环显示
//展示菜单
wm.showMenu();
std::cout << "请输入您的选择:" << std::endl;
std::cin >> choice;
switch (choice) {//功能选择
case 0://退出系统
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;
}
5.2 实现退出功能
在workerManager.h
中提供退出系统的成员函数 void exitSystem();
在workerManager.cpp
中提供具体的功能实现
//退出程序
void WorkerManager::exitSystem() {
std::cout << "欢迎下次使用" << std::endl;
system("pause");
exit(0);// 清理I/O缓冲区后再退出进程
}
5.3测试功能
在main函数分支 0 选项中,调用退出程序的接口
6、创建职工类
6.1 创建职工抽象类
职工的分类为:普通员工、经理、老板
将三种职工抽象到一个类(worker)中,利用多态管理不同职工种类
职工的属性为:职工编号、职工姓名、职工所在部门编号
职工的行为为:岗位职责信息描述,获取岗位名称
头文件文件夹下 创建文件worker.h
文件并且添加如下代码:
- 因为是基类而且不需要实现,所以没有
cpp
文件
#ifndef WORK_H
#define WORK_H
#include<iostream>
//职工抽象基类
class Work {
public:
//显示职位信息
virtual void showInfo() = 0;//纯虚数函数
//获取岗位名称
virtual std::string getDeptName() = 0;
public:
int id;//职工编号
std::string name;//职工姓名
int deptId;//职工所在部门编号
};
#endif
6.2 创建普通员工类
普通员工类继承职工抽象类,并重写父类中纯虚函数
在头文件和源文件的文件夹下分别创建employee.h
和 employee.cpp
文件
employee.h
中代码如下:
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "worker.h"
//普通员工类
class Employee:public Worker {
public:
//构造函数
Employee(int id, std::string name, int dId);
//显示个人信息
virtual void showInfo();//必须重写
//获取职工岗位名称
virtual std::string getDeptName();//必须重写
};
#endif
employee.cpp
中代码如下:
#include "employee.h"
//构造函数
Employee::Employee(int id, std::string name, int dId) {
this->id = id;
this->name = name;
this->deptId = dId;
}
//显示个人信息
void Employee::showInfo() {
std::cout << "职工编号:" << this->id
<< "\t职工姓名:" << this->name
<< "\t岗位:" << this->getDeptName()
<< "\t岗位职责:完成经理交代的任务" << std::endl;
}
//获取岗位名称
std::string Employee::getDeptName() {
return std::string("员工");
}
6.3 创建经理类
经理类继承职工抽象类,并重写父类中纯虚函数,和普通员工类似
在头文件和源文件的文件夹下分别创建manager.h
和 manager.cpp
文件
manager.h
中代码如下:
#ifndef MANAGER_H
#define MANAGER_H
#include "worker.h"
//经理类
class Manager :public Worker {
//构造函数
Manager(int id, std::string name, int dId);
//显示个人信息
virtual void showInfo();
//获取职工岗位名称
virtual std::string getDeptName();
};
#endif
manager.cpp
中代码如下:
#include "manager.h"
//经理类
//构造函数
Manager::Manager(int id, std::string name, int dId) {
this->id = id;
this->name = name;
this->deptId = dId;
}
//显示个人信息
void Manager::showInfo() {
std::cout << "职工编号:" << this->id
<< "\t职工姓名:" << this->name
<< "\t岗位:" << this->getDeptName()
<< "\t岗位职责:完成老板交代的任务,下发任务给员工" << std::endl;
}
//获取岗位信息
std::string Manager::getDeptName() {
return std::string("经理");
}
6.4 创建老板类
老板类继承职工抽象类,并重写父类中纯虚函数,和普通员工类似
在头文件和源文件的文件夹下分别创建boss.h
和 boss.cpp
文件
boss.h
中代码如下:
#ifndef BOSS_H
#define BOSS_H
#include"worker.h"
//老板类
class Boss :public Worker {
//构造函数
Boss(int id, std::string name, int dId);
//显示个人信息
virtual void getInfo();
//获取职位信息
virtual std::string getDeptName();
};
#endif
boss.cpp
中代码如下:
#include"boss.h"
//老板类
//构造函数
Boss::Boss(int id, std::string name, int dId) {
this->id = id;
this->name = name;
this->deptId = dId;
}
//显示个人信息
void Boss::getInfo() {
std::cout << "职工编号:" << this->id
<< "\t职工姓名:" << this->name
<< "\t岗位:" << this->getDeptName()
<< "\t岗位职责:管理公司所有事务" << std::endl;
}
//获取职位信息
std::string Boss::getDeptName() {
return std::string("总裁");
}
6.5 测试多态
在职工管理系统.cpp
中添加测试函数,并且运行能够产生多态
测试代码如下:
#include<iostream>
#include "workerManager.h" //职工类
#include"worker.h" //职工抽象基类
#include"employee.h" //员工类
#include"manager.h" //管理类
#include"boss.h" //老板类
//测试多态
void test() {
Worker* worker = NULL;
worker = new Employee(1, "张三", 1);
worker->showInfo();
delete worker;
Worker* worker2 = NULL;
worker2 = new Manager(2, "李四", 1);
worker2->showInfo();
delete worker2;
Worker* worker3 = NULL;
worker3 = new Boss(3, "王五", 1);
worker3->showInfo();
delete worker3;
}
测试成功后,测试代码可以注释保留,或者选择删除
7、添加职工
功能描述:批量添加职工,并且保存到文件中
7.1 功能分析
分析:
用户在批量创建时,可能会创建不同种类的职工
如果想将所有不同种类的员工都放入到一个数组中,可以将所有员工的指针维护到一个数组里
如果想在程序中维护这个不定长度的数组,可以将数组创建到堆区,并利用Worker **的指针维护
7.2 功能实现
在WokerManager.h
头文件中添加成员属性 代码:
#include "worker.h"
//记录文件中的人数个数
int m_EmpNum;
//员工数组的指针
Worker ** m_EmpArray;//定义指向数据为指针的指针
在WorkerManager
构造函数中初始化属性
WorkerManager::WorkerManager()
{
//初始化人数
this->m_EmpNum = 0;
//初始化数组指针
this->m_EmpArray = NULL;
}
在workerManager.h
中添加成员函数
//增加职工
void Add_Emp();
workerManager.cpp
中实现该函数
#include "workerManager.h" //职工类
#include"worker.h" //职工抽象基类
#include"employee.h" //员工类
#include"manager.h" //管理类
#include"boss.h" //老板类
//增加职工
void WorkerManager::addEmp() {
std::cout << "请输入增加职工数量:";
int addNum = 0;
std::cin >> addNum;
if (addNum > 0) {//输入数据合法
//计算新空间大小
int newSize = this->empNum + addNum;
//开辟新空间
Worker** newSpace = new Worker * [newSize];
//将原有空间下内容转移到新空间中
if (this->empArray != NULL) {//原有数据存在
for (int i = 0; i < this->empNum; i++) {
if (i < newSize) {//如果没有判断报错C6386 虽然似乎报错没有什么意义
newSpace[i] = this->empArray[i];
}
}
}
//输入新数据
for (int i = 0; i < addNum; i++) {
int id;
std::string name;
int dId;
//信息输入
//编号
std::cout << "请输入第" << i + 1 << "个职工编号:";
std::cin >> id;
//姓名
std::cout << "请输入第" << i + 1 << "个职工姓名:";
std::cin >> name;
//岗位选择
int state = 0;
std::cout << "请选择该职工的岗位:" << std::endl;
std::cout << "1、普通职工" << std::endl;
std::cout << "2、经理" << std::endl;
std::cout << "3、老板" << std::endl;
do {
state = 0;//默认执行一次
std::cout << "选择该职工的岗位:" << std::endl;
std::cin >> dId;
if (dId != 1 && dId != 2 && dId != 3) {//不合法重复执行
state = 1;
}
} while (state);
//信息录入
Worker* worker = NULL;
switch (dId) {//根据职位调用不同函数
case 1://普通员工
worker = new Employee(id, name, 1);
break;
case 2://经理
worker = new Manager(id, name, 2);
break;
case 3://老板
worker = new Boss(id, name, 3);
break;
default://意外不保存
break;
}
//存入新空间
int t = this->empNum + i;
if (t <newSize) {//不判断同上警报报错
newSpace[t] = worker;
}
}
//释放原有空间
delete[] this->empArray; //释放数组空间
//更改新空间指向
this->empArray = newSpace;
//更新个数
this->empNum = newSize;
//提示信息
std::cout << "\n成功添加" << addNum << " 名新职工!" << std::endl;
}
else {//输入数据不合法
std::cout << "输入数据不合法" << std::endl;
}
system("pause");
system("cls");
}
在WorkerManager.cpp
的析构函数中,释放堆区数据
WorkerManager::~WorkerManager()
{
if (this->m_EmpArray != NULL)
{
delete[] this->m_EmpArray;
}
}
7.3 测试添加
在main函数分支 1 选项中,调用添加职工接口
至此,添加职工到程序中功能实现完毕
8、文件交互 - 写文件
功能描述:对文件进行读写
在上一个添加功能中,我们只是将所有的数据添加到了内存中,一旦程序结束就无法保存了
因此文件管理类中需要一个与文件进行交互的功能,对于文件进行读写操作
8.1 设定文件路径
首先我们将文件路径,在workerManager.h
中添加宏常量,并且包含头文件 fstream
#include <fstream>
#define FILENAME "empFile.txt"
8.2 成员函数声明
在workerManager.h
中类里添加成员函数 void save()
//保存文件
void save();
8.3 保存文件功能实现
void WorkerManager::save()
{
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;
}
ofs.close();
}
8.4 保存文件功能测试
在添加职工功能中添加成功后添加保存文件函数
再次运行代码,添加职工
同级目录下多出文件,并且保存了添加的信息
9、文件交互 - 读文件
功能描述:将文件中的内容读取到程序中
虽然我们实现了添加职工后保存到文件的操作,但是每次开始运行程序,并没有将文件中数据读取到程序中
而我们的程序功能中还有清空文件的需求
因此构造函数初始化数据的情况分为三种
- 第一次使用,文件未创建
- 文件存在,但是数据被用户清空
- 文件存在,并且保存职工的所有数据
9.1 文件未创建
在workerManager.h
中添加新的成员属性 m_FileIsEmpty
标志文件是否为空
//标志文件是否为空
bool m_FileIsEmpty;
修改WorkerManager.cpp
中构造函数代码
//职工类构造函数
WorkerManager::WorkerManager() {
std::ifstream ifs;//文件读取流对象
ifs.open(FILENAME, std::ios::in);
//文件不存在
if (!ifs.is_open()) {
//std::cout << "文件不存在" << std::endl;//测试输出
this->empNum = 0;//初始化人数
this->fileIsEmpty = true;//初始化文件为空标志
this->empArray = NULL;//初始化数组指针
ifs.close();//关闭文件
return;
}
}
删除文件后,测试文件不存在时初始化数据功能
9.2 文件存在且数据为空
在workerManager.cpp
中的构造函数追加代码:
//文件存在-没有记录
char ch;
ifs >> ch;//读取一个字符--如果为空读取的时文件结束判断位
if (ifs.eof()) {//到达文件尾
this->empNum = 0;//初始化人数
this->fileIsEmpty = true;//初始化文件为空标志
this->empArray = NULL;//初始化数组指针
ifs.close();//关闭文件
return;
}
将文件创建后清空文件内容,并测试该情况下初始化功能
我们发现文件不存在或者为空清空 m_FileIsEmpty 判断文件是否为空的标志都为真,那何时为假?
成功添加职工后,应该更改文件不为空的标志
在void WorkerManager::Add_Emp()
成员函数中添加:
//更新职工不为空标志
this->fileIsEmpty = false;
9.3 文件存在且保存职工数据
9.3.1 获取记录的职工人数
在workerManager.h
中添加成员函数 int get_EmpNum();
//统计人数
int get_EmpNum();
workerManager.cpp
中实现
//统计文件中的人数
int WorkerManager::getNum() {//通过读取文件获取文件数目
std::ifstream ifs;
ifs.open(FILENAME, std::ios::in);//读取
//中间变量
int id;
std::string name;
int dId;
int num = 0;//统计数据
while (ifs >> id && ifs >> name && ifs >> dId) {//每次从文件中读取三个数据(一组为一个人的)
//记录人数
num++;
}
ifs.close();//关闭文件
return num;//返回数据
}
在workerManager.cpp
构造函数中继续追加代码:
//文件存在有数据
int num = this->getNum();
std::cout << "职工个数为:" << num << std::endl;
this->empNum = num;//更新成员属性
手动添加一些职工数据,测试获取职工数量函数
9.3.2 初始化数组
根据职工的数据以及职工数据,初始化workerManager
中的Worker ** m_EmpArray
指针
在WorkerManager.h
中添加成员函数 void init_Emp();
//初始化文件中员工
void initEmp();
在WorkerManager.cpp
中实现
//初始化文件中的员工
void WorkerManager::initEmp() {//从文件中读取对象数据并存储到数组中
std::ifstream ifs;
ifs.open(FILENAME, std::ios::in);//读取文件
int id;
std::string name;
int dId;
int index = 0;
while (ifs >> id && ifs >> name && ifs >> dId) {
Worker* worker = NULL;
//根据不同职位创建不同的对象
if (dId == 1) {//1 普通员工
worker = new Employee(id, name, dId);
}
else if (dId == 2) {//2 经理
worker = new Manager(id, name, dId);
}
else if (dId == 3) {//3 老板
worker = new Boss(id, name, dId);
}
//存放在数组中
this->empArray[index] = worker;
index++;
}
}
在workerManager.cpp
构造函数中追加代码
//根据职工数创建数组
this->empArray = new Worker * [this->empNum];
//初始化职工到数组
initEmp();
//测试初始化
/*for (int i = 0; i < empNum; i++) {
std::cout << "职工号:" << this->empArray[i]->id
<< "\t职工姓名:" << this->empArray[i]->name
<< "\t部门编号:" << this->empArray[i]->deptId << std::endl;
}*/
运行程序,测试从文件中获取的数据
至此初始化数据功能完毕,测试代码可以注释或删除掉!
10、显示职工
功能描述:显示当前所有职工信息
10.1 显示职工函数声明
在workerManager.h
添加成员函数 void Show_Emp();
//显示职工
void Show_Emp();
10.2 显示职工函数实现
在workerManager.cpp
中实现成员函数 void Show_Emp();
//显示职工
void WorkerManager::showEmp() {
//判断数据存不存在
if (this->fileIsEmpty) {
std::cout << "文件不存在或者为空" << std::endl;
}
else {
for (int i = 0; i < empNum; i++) {
//利用多态调用接口
this->empArray[i]->showInfo();
}
}
//暂停屏幕
system("pause");
system("cls");
}
10.3 测试显示职工
在main函数分支 2 选项中,调用显示职工接口
测试时分别测试 文件为空和文件不为空两种情况
测试1-文件不存在或者为空情况
测试2 - 文件存在且有记录情况
测试完毕,至此,显示所有职工信息功能实现
11、删除职工
功能描述:按照职工的编号进行删除职工操作
11.1 删除职工函数声明
在workerManager.h
中添加成员函数 void Del_Emp();
//删除职工
void delEmp();
11.2 职工是否存在函数声明
很多功能都需要用到根据职工是否存在来进行操作如:删除职工、修改职工、查找职工
因此添加该公告函数,以便后续调用
在workerManager.h
中添加成员函数 int IsExist(int id);
//按照职工编号判断职工是否存在,若存在返回职工在数组中位置,不存在返回-1
int isExit(int id);
11.3 职工是否存在函数实现
在workerManager.cpp
中实现成员函数 int IsExist(int id);
//按照职工编号判断职工是否存在,若存在返回职工在数组中位置,不存在返回-1
int WorkerManager::isExit(int id) {
int index = -1;
for (int i = 0; i < this->empNum; i++) {
if (this->empArray[i]->id == id) {//职工号存在
index = i;
break;
}
}
return index;
}
11.4 删除职工函数实现
在workerManager.cpp
中实现成员函数 void Del_Emp();
//删除职工
void WorkerManager::delEmp() {
//1 文件不存在或者无数据
if (this->fileIsEmpty) {
std::cout << "文件不存在或者记录为空" << std::endl;
}
else {
//按照职工编号删除
std::cout << "请输入想要删除的职工号:";
int id = 0;
std::cin >> id;
int index = this->isExit(id);
if (index != -1) {//数据存在
for (int i = index; i < this->empNum; i++) {//从待删除数据往后数据前移
this->empArray[i] = this->empArray[i + 1];
}
this->empNum--;
this->save();//删除后数据同步到文件
std::cout << "删除成功" << std::endl;
}
else {//数据不存在
std::cout << "删除失败,未找到该职工" << std::endl;
}
}
system("pause");
system("cls");
}
11.5 测试删除职工
在main函数分支 3 选项中,调用删除职工接口
测试1 - 删除不存在职工情况
测试2 - 删除存在的职工情况
再次显示所有职工信息,确保已经删除
查看文件中信息,再次核实员工已被完全删除
至此,删除职工功能实现完毕!
12、修改职工
功能描述:能够按照职工的编号对职工信息进行修改并保存
12.1 修改职工函数声明
在workerManager.h
中添加成员函数 void Mod_Emp();
//修改职工
void modEmp();
12.2 修改职工函数实现
在workerManager.cpp
中实现成员函数 void Mod_Emp();
//修改职工
void WorkerManager::modEmp() {
if (this->fileIsEmpty) {//文件不存在或者为空
std::cout << "文件不存在或者记录为空" << std::endl;
}
else {
std::cout << "请输入修改职工的编号:";
int id;
std::cin >> id;
int index = this->isExit(id);
if (index != -1) {//职工号存在
//获取原有数据
int id = this->empArray[index]->id;
std::string name = this->empArray[index]->name;
int dId = this->empArray[index]->deptId;
//修改数据
//姓名
std::cout << "原有姓名:" <<name<< "修改为姓名:";
std::cin >> name;
//岗位选择
int state = 0;
std::cout << "原有岗位:"<<dId<<"请选择该职工的岗位:" << std::endl;
std::cout << "1、普通职工" << std::endl;
std::cout << "2、经理" << std::endl;
std::cout << "3、老板" << std::endl;
do {
state = 0;//默认执行一次
std::cout << "选择该职工的岗位:";
std::cin >> dId;
if (dId != 1 && dId != 2 && dId != 3) {//不合法重复执行
state = 1;
}
} while (state);
//信息录入
Worker* worker = NULL;
switch (dId) {//根据职位调用不同函数
case 1://普通员工
worker = new Employee(id, name, 1);
break;
case 2://经理
worker = new Manager(id, name, 2);
break;
case 3://老板
worker = new Boss(id, name, 3);
break;
default://意外不保存
break;
}
//删除原有数据
delete this->empArray[index];
//更新数据,数据保存
this->empArray[index] = worker;
//修改完成提示
std::cout << "修改完成" << std::endl;
//保存到文件中
this->save();
}
else {
std::cout << "修改失败,查无此人" << std::endl;
}
}
//按任意按键 清屏
system("pause");
system("cls");
}
12.3 测试修改职工
在main函数分支 4 选项中,调用修改职工接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVB7wraX-1675440464800)(null)]
测试1 - 修改不存在职工情况
测试2 - 修改存在职工情况,例如将职工 “李四” 改为 “赵四”
修改后再次查看所有职工信息,并确认修改成功
再次确认文件中信息也同步更新
至此,修改职工功能已实现!
13、查找职工
功能描述:提供两种查找职工方式,一种按照职工编号,一种按照职工姓名
13.1 查找职工函数声明
在workerManager.h
中添加成员函数 void Find_Emp();
//查找职工
void findEmp();
13.2 查找职工函数实现
在workerManager.cpp
中实现成员函数 void Find_Emp();
//查找职工
void WorkerManager::findEmp() {
//文件不存在或者数据为空
if (this->fileIsEmpty) {
std::cout << "文件不存在或者数据为空" << std::endl;
}
else {
std::cout << "请选择查找方式:" << std::endl
<< "1 按照职工编号查找" << std::endl
<< "2 按照职工姓名查找" << std::endl;
int select = 0;
do {//查找选择
std::cout << "查找方式:";
std::cin >> select;
} while (select != 1 && select != 2);
if (select == 1) {// 按照职工编号查找
int id;
std::cout << "请输入职工编号:";
std::cin >> id;
int index = isExit(id);//判断数据是否存在
if (index != -1) {
std::cout << "查找成功,职工信息如下:" << std::endl;
this->empArray[index]->showInfo();
}
else {
std::cout << "查找失败,查无此人" << std::endl;
}
}
else if (select == 2) {//按照姓名查找
std::string name;
std::cout << "请输入查找的姓名:";
std::cin >> name;
//比对信息
bool flag = false;//查找标志
for (int i = 0; i < empNum; i++) {
if (this->empArray[i]->name == name) {
std::cout << "查找成功!姓名为" << name
<< "的信息如下:"<<std::endl;
flag = true;
this->empArray[i]->showInfo();
}
}
if (flag == false) {//查找失败
std::cout << "查询失败,查无此人" << std::endl;
}
}
else {
std::cout << "输入选项错误" << std::endl;
}
}
system("pause");
system("cls");
}
13.3 测试查找职工
在main函数分支 5 选项中,调用查找职工接口
测试1 - 按照职工编号查找 - 查找不存在职工
测试2 - 按照职工编号查找 - 查找存在职工
测试3 - 按照职工姓名查找 - 查找不存在职工
测试4 - 按照职工姓名查找 - 查找存在职工(如果出现重名,也一并显示,在文件中可以添加重名职工)
例如 添加两个王五的职工,然后按照姓名查找王五
至此,查找职工功能实现完毕!
14、排序
功能描述:按照职工编号进行排序,排序的顺序由用户指定
14.1 排序函数声明
在workerManager.h
中添加成员函数 void Sort_Emp();
//排序职工
void sortEmp();
14.2 排序函数实现
在workerManager.cpp
中实现成员函数 void Sort_Emp();
//排序职工信息
void WorkerManager::sortEmp() {
//文件不存在或者数据为空
if (this->fileIsEmpty) {
std::cout << "文件不存在或者信息为空" << std::endl;
}
else {
std::cout<< "请选择排序方式:" << std::endl
<< "1 按职工号升序排序" << std::endl
<< "2 安置工号降序排列" << std::endl;
int select = 0;
do {
std::cout << "选择排序:";
std::cin >> select;
} while (select != 1 && select != 2);
//选择排序
for (int i = 0; i < empNum; i++) {
int Max = i;
for (int j = i + 1; j < empNum; j++) {
//升序排列
if (select == 1) {
if (empArray[Max]->id > empArray[j]->id) {
Max = j;
}
}
else {//降序排序
if (empArray[Max]->id < empArray[j]->id) {
Max = j;
}
}
}
if (i != Max) {//数据交换--每次大循环的最大/小值
Worker* temp = empArray[i];
empArray[i] = empArray[Max];
empArray[Max] = temp;
}
}
std::cout << "排序成功,排序后的结果为:" << std::endl;
this->save();//保存到文件
this->showEmp();
}
}
14.3 测试排序功能
在main函数分支 6 选项中,调用排序职工接口
测试:
首先我们添加一些职工,序号是无序的
测试 - 升序排序 文件同步更新
测试 - 降序排序 文件同步更新
至此,职工按照编号排序的功能实现完毕!
15、清空文件
功能描述:将文件中记录数据清空
15.1 清空函数声明
在workerManager.h
中添加成员函数 void Clean_File();
//清空文件
void clearFile();
15.2 清空函数实现
在workerManager.cpp
中实现员函数 void Clean_File();
//清空文件
void WorkerManager::clearFile() {
//确认提示
int select = 0;
do {
std::cout << "你确认要清空?" << std::endl
<< "1 确认" << std::endl
<< "2 返回" << std::endl
<< "选择:";
std::cin >> select;
} while (select != 1 && select != 2);
//清空文件
if (select == 1) {
//文件清空
std::ofstream ofs(FILENAME, std::ios::trunc);//如果文件存在,先删除再建立
ofs.close();
//清空堆区对象
if (this->empArray != NULL) {
//删除堆区的每个职工对象
for (int i = 0; i < empNum; i++) {
if (this->empArray[i] != NULL) {
delete this->empArray[i];//释放每个堆区对象
}
}
//删除堆区数组指针
delete[] this->empArray;
this->empArray = NULL;
this->empNum = 0;
this->fileIsEmpty = true;
}
std::cout << "清除成功!" << std::endl;
}
system("pause");
system("cls");
}
15.3 测试清空文件
在main函数分支 7 选项中,调用清空文件接口
测试:确认清空文件
再次查看文件中数据,记录已为空
打开文件,里面数据已确保清空,该功能需要慎用!
随着清空文件功能实现,本案例制作完毕 ^ _ ^