职工管理系统

我们已经了解了C++面向对象的编程思想。现在我们利用多态的技术,来实现一个职工管理系统,对这些知识加以巩固和提升。

公司里面职工分为三类:

  • 普通员工:完成经理交给的任务;
  • 经理:完成老板交给的任务,并下发任务给员工;
  • 老板:管理公司中所有事务。

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

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

创建主文件

  • MainSystem.cpp 存放main函数。
#include <iostream>
#include <fstream>
#include <string>

using namespace std;


int main(void)
{
    return 0;
}

创建管理类

管理类负责内容如下:

  • 与用户沟通的菜单界面
  • 对职工增删改查的操作
  • 与文件的读写交互

创建文件

分别创建workerManager.h和workerManager.cpp

  • workerManager.h
#pragma once
#include <iostream>
using namespace std;

class WorkerManager
{
public:
    //头文件只有声明,在源文件中实现
    WorkerManager();//构造函数
    ~WorkerManager(); //析构函数
};
  • workerManager.cpp
#include "workerManager.h"

//源文件中实现
WorkerManager::WorkerManager()
{
    
}

WorkerManager::~WorkerManager()
{
    
}

菜单功能

在管理类WorkerManager中添加成员函数void showManu()。并在对应源文件实现,代码如下:

void WorkerManager::showManu()
{
    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;
}

测试:

下面我们在主函数中写入相应代码:

#include <iostream>
#include <fstream>
#include <string>
#include"workerManager.h"

using namespace std;

int main(void)
{
    WorkerManager wm; //实例化管理者对象
    wm.showManu(); //调用显示菜单函数

    system("pause");
    return 0;
}

测试结果如下:
image

退出功能

我们本着先易后难的原则,先实现一个最容易实现的功能,退出功能。
在main函数中提供分支选择,提供每个功能接口:

int main(void)
{
    WorkerManager wm; //实例化管理者对象
    int choice = 0;
    while (true)
    {
        wm.showManu(); //调用显示菜单函数
        cout << "请输入您的选择:" << endl;
        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;
}

退出功能实现

在workerManager类中声明函数:void exitSystem();
并在对应.cpp源文件中实现:

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

测试

在主函数中分支0选项中,调用该退出函数。

测试结果如下:
image.png

创建职工类

职工分为普通员工,经理,老板。我们将三种职工抽象到一个类(worker)中,利用多态管理不同职工的种类。职工的属性为:职工编号,姓名,部门ID.行为有:岗位职责描述,获取岗位名称。

创建worker.h

Worker类作为抽象基类,没有必要创建对应的cpp文件。代码如下:

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

//职工类基类
class Worker
{
public:
    int m_ID; //职工编号
    string m_Name; //职工姓名
    int m_DeptID; //部门编号

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

    //获取岗位名称
    virtual string getDeptName() = 0;
};

创建普通员工类

普通职工类继承职工抽象类,重写父类虚函数。分别创建employee.h和employee.cpp。

  • employee.h
//普通员工文件 继承worker类
#pragma once
#include "worker.h"
using namespace std;

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

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

    //获取岗位名称
    virtual string getDeptName();
};
  • employee.cpp
#include "employee.h"

Employee::Employee(int id, string name, int dId) //构造函数
{
    this->m_DeptID = dId;
    this->m_Name = name;
    this->m_ID = id;
}
//显示个人信息
void Employee::showInfo()
{
    cout << "职工编号:" << this->m_ID
         << "\t职工姓名:" << this->m_Name
         << "\t岗位:" << this->getDeptName()
         << "\t岗位职责:完成经理交给的任务" << endl;
}

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

创建经理类

经理类继承职工抽象类,重写父类虚函数。分别创建manager.h和manager.cpp。

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

//经理类
class Manager : public Worker
{
public:
    Manager(int id, string name, int dId); //构造函数

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

    //获取岗位名称
    virtual string getDeptName();
};
  • manager.cpp
#include "manager.h"

Manager::Manager(int id, string name, int dId) //构造函数
{
    this->m_DeptID = dId;
    this->m_Name = name;
    this->m_ID = id;
}
//显示个人信息
void Manager::showInfo()
{
    cout << "职工编号:" << this->m_ID
         << "\t职工姓名:" << this->m_Name
         << "\t岗位:" << this->getDeptName()
         << "\t岗位职责:完成老板交给的任务,并下发任务给员工" << endl;
}

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

创建老板类

与前者一样,老板继类承职工抽象类,重写父类虚函数。分别创建boss.h和boss.cpp。

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

//经理类
class Boss : public Worker
{
public:
    Boss(int id, string name, int dId); //构造函数

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

    //获取岗位名称
    virtual string getDeptName();
};
  • boss. cpp
#include "boss.h"

Boss::Boss(int id, string name, int dId) //构造函数
{
    this->m_DeptID = dId;
    this->m_Name = name;
    this->m_ID = id;
}

//显示个人信息
void Boss::showInfo()
{
    cout << "职工编号:" << this->m_ID
         << "\t职工姓名:" << this->m_Name
         << "\t岗位:" << this->getDeptName()
         << "\t岗位职责:管理公司所有事物" << endl;
}

//获取岗位名称
string Boss::getDeptName()
{
    return string("总裁");
}

测试

在主函数写如下代码,进行测试:

#include <string>
#include "workerManager.h"
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

using namespace std;

int main(void)
{
    //测试代码
    Worker *worker = NULL;
    worker = new Employee(1, "张三", 1);
    worker->showInfo();
    delete worker;

    worker = new Manager(2, "李四", 2);
    worker->showInfo();
    delete worker;

    worker = new Boss(3, "王五", 3);
    worker->showInfo();
    delete worker;

    system("pause");
    return 0;
}

测试结果:
image.png

可以看到,多态测试成功。

添加职工

功能分析:

在用户批量创建的时候,可能会创建不同种类的员工。我们可以在堆区开辟一个动态的指针数组,存放Worker*类型的指针,并用一个Worker**类型的指针进行维护。Worker*类型指针是一个父类指针,是可以指向不同的子类的对象的。
如下图:

worker**
如果这个数组已经满了,但是还要再添加职工。我们需要在开辟一个新的更长的数组,并把原来数组的数据拷贝到新数组,在新数组里面添加数据,并释放掉原先的数组。

功能实现

在WorkerManager类中添加成员属性:

    //记录职工人数
    int m_EmpNum;

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

在WorkerManager构造函数中初始化属性

WorkerManager::WorkerManager()
{
    //初始化属性
    this->m_EmpNum = 0;

    this->m_EmpArray = NULL;
}

在WorkerManager类中添加成员函数

    //添加职工
    void add_Emp();

在workerManager.cpp中实现成员函数

/添加职工
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, 2);
            case 3:
                worker = new Boss(id, name, 3);
            default:
                break;
            }

            //将创建的职工指针保存到数组中
            newSpace[this->m_EmpNum + i] = worker;
        }

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

        //更改新空间的指向
        this->m_EmpArray = newSpace;
        
        //更新职工人数
        this->m_EmpNum = newSize;

        //提示添加成功
        cout << "成功添加" << addNum <<"名新职工"<< endl;
    }
    else
    {
        cout << "输入有误!" << endl;
    }
}

释放空间

在析构函数中把在堆区开辟的数据给释放掉。不能仅仅释放数组,要先释放每一个数组内的指针所维护的开辟在堆区的对对象,最后再释放数组,算彻底释放空间。

//析构函数,释放堆区数据
WorkerManager::~WorkerManager()
{
    if (this->m_EmpArray != NULL)
    {
        //删除堆区每一个职工对象
        for (int i = 0; i < this->m_EmpNum; i++)
        {
            delete this->m_EmpArray[i];
            this->m_EmpArray[i] = NULL;
        }

        delete[] this->m_EmpArray;
        this->m_EmpArray = NULL;
    }
}

测试

image.png

我们注意到当前文件夹下多了一个worker.txt文件:
worker

可以看到,我们的写文件功能已经实现。

读文件

到目前为止,我们虽然创建了文件,但是程序打开后的数据是为空的。因为我们并没有把文件数据从硬盘中读回来。这就要求在程序开始运行的时候要有一个初始化的操作,把数据读到内存中来。因而就要分以下几种情况来考虑:

(一)文件未创建

在WorkerManager类中添加成员属性m_FileIsEmpty标志文件是否为空:

   //文件是否为空标志
    bool m_FileIsEmpty;

一旦判断文件不存在,初始化人数为0、文件标志为空、数组为空。在workerManager.cpp中修改构造函数:

WorkerManager::WorkerManager()
{
 
    ifstream ifs;
    
    //1、文件不存在
    ifs.open(FILE_NAME, ios::in);
    if (ifs.is_open() == NULL)
    {
        cout << "文件不存在!" << endl;
        //初始化人数为0
        this->m_EmpNum = 0;

        //初始化文件为空
        this->m_FileIsEmpty = true;
        ifs.close();
        return;
    }
}

(二)文件数据为空

文件存在,但数据已经被用户清空,这种情况,我们该怎么判断呢?可以尝试着从文件中读取一个字符,如果读到的是文件结尾标志EOF,说明文件内容为空。在构造函数中追加以下代码:

    //2、文件存在 数据为空
    char ch;
    ifs >> ch; //从文件中读取一个字符
    if(ifs.eof())  //判断读取到的是否为EOF
    {
        //文件为空
        cout << "文件为空!" << endl;
        //初始化人数为0
        this->m_EmpNum = 0;

        //初始化文件为空
        this->m_FileIsEmpty = true;
        ifs.close();
        return;
    }

这里要有一个注意事项:我们添加了文件是否为空的一个标记变量,要注意每次在添加完员工信息之后,要将其值修改为false,否则在后续的操作过程中会出现bug。

(三)文件中已经有数据

  • 获取职工人数
    在WorkerManager类中添加成员函数int get_EmpNum();,统计文件中记录的员工个数
    //统计文件中人数   
    int get_EmpNum();

workerManager.cpp中实现

//统计文件中人数
int WorkerManager::get_EmpNum()
{
    ifstream ifs;
    ifs.open(FILE_NAME, ios::in);
    int id;
    string name;
    int dId;

    int num = 0;  //人数,初始化为0
    while (ifs >> id && ifs >> name && ifs >> dId)
    {
        num++; //每读取一行,人数加一
    }
    ifs.close();
    return num;
}

构造函数中追加代码

    //3、文件存在,并且已经有数据
    this->m_EmpNum = this->get_EmpNum(); //统计职工人数
    this->m_FileIsEmpty = false;
    cout << "职工人数为:" << this->m_EmpNum << endl
  • 初始化数组
    根据职工的人数,初始化workerManager类中的Worker** m_EmpArray指针;
    在WorkerManager类中添加成员函数 void init_Emp()
//初始化员工
void init_Emp();

在workerManager.cpp中实现

//统计文件中人数
int WorkerManager::get_EmpNum()
{
    ifstream ifs;
    ifs.open(FILE_NAME, ios::in);
    int id;
    string name;
    int dId;

    int num = 0;
    while (ifs >> id && ifs >> name && ifs >> dId)
    {
        num++;
    }
    ifs.close();
    return num;
}

//初始化员工
void WorkerManager::init_Emp()
{
    ifstream ifs;
    ifs.open(FILE_NAME, 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();
}

在构造函数中追加一下代码:

//开辟空间
    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
             << " 姓名:" << this->m_EmpArray[i]->m_Name
             << " 部门编号:" << this->m_EmpArray[i]->m_DeptID << endl;
    }

测试功能

  • 文件不存在

    我们删除已经创建好的文件,运行程序:
    文件不存在
  • 文件为空

    从回收站中恢复文件,并清空内容:
    文件为空
  • 文件存不为空
    我们手动添加一些数据:


    worker.txt

    测试结果:
    文件不为空
    可以看到,测试结果与预期一致。

显示职工

在WorkerManager类中添加函数void show_Emp();

    //显示职工
    void show_Emp();

在workerManager.cpp中实现

//显示职工
void WorkerManager::show_Emp()
{
    //判断文件是否为空
    if(this->m_FileIsEmpty == true)
    {
        cout << "文件不存在,或者记录为空!" << endl;
    }
    else
    {
        for (int i = 0; i < m_EmpNum; i++)
        {
            //利用对多态调用程序接口
            this->m_EmpArray[i]->showInfo();
        }
    }

    system("pause");
    system("cls");
}
  • 测试
  1. 文件不为空:
    显示职工
  2. 文件为空:
    显示职工

删除职工

  • 功能:传入一个ID号,按ID来删除员工
    在删除职工之前,我们先来实现一下一个判断职工是否存在的函数
    在WorkerManager类中添加成员函数 int isExit(int Id)
    //判断职工是否存在
    int isExit(int Id);

在workerManager.cpp中实现该函数。遍历数组,找到与传入Id一致的职工,返回该值职工在数组中的位置,否则返回-1;

//判断职工是否存在
int WorkerManager::isExit(int Id)
{
    int index = -1;
    for (int i = 0; i < this->m_EmpNum; i++)
    {
        if (this->m_EmpArray[i]->m_ID == Id)
        {
            index = i;  //找到返回 i
            return index;
        }
    }
    return index; //没找到返回-1;
}

下面我们来考虑删除职工的问题。

在WorkerManager类中添加成员函数 void del_Emp()

    //删除职工
    void del_Emp();

在workerManager.cpp中实现该函数。我们维护的是一个数组,对于数组的删除,我们需要找到要删除的元素的位置,从这一个位置到倒数第二个位置结束,后面的元素依次向前一个元素移动。最后记录数组元素个数的变量值减一即可。

//删除职工
void WorkerManager::del_Emp()
{
    if(this->m_FileIsEmpty)
    {
        cout << "文件不存在,或者记录为空!" << endl;
    }
    else
    {
        //按照职工编号删除
        cout << "请输入要删除的职工编号:" << endl;
        int id;
        cin >> id;
        int index = this->isExit(id);
        if (index != -1)//说明职工存在,接下来要删除掉index位置上的职工
        {
            //从第index个数据开始,之后的数据往前移动一个位置
            for (int i = index; i < this->m_EmpNum - 1; i++)
            {
                this->m_EmpArray[i] = this->m_EmpArray[i + 1];
            }
            
            //更新一下数组中的人员个数
            this->m_EmpNum--;

            //同步更新到文件中
            this->save();
            cout<< "删除成功!" << endl;
        }
        else
        {
            cout << "该职工不存在!" << endl;
        } 
    }

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

测试

1.删除已存在的员工:

现在我们的文件里有4个职工信息:
worker.txt
我们将它显示出来:
显示

删除一个员工信息:
删除
我们再来查看一下:
再查看
还有文件内容:
worker.txt
可以看到,删除成功,连同文件内容一起删除。
  1. 删除不存在的员工

    我们已经把1号员工删除了,我们再来删除一次,看看会不会按我们预期输出:
    员工不存在
    测试成功。

修改职工

按照职工的编号对职工的信息进行修改并保存
在WorkerManager类中添加成员函数void mod_Emp();

//修改职工
void mod_Emp();

在workerManager.cpp中实现该函数。根据用户输入的ID号,调用isExit()函数找到它在数组中的位置,删除它。然后再new出来一个新的员工,输入对应的信息之后,放到数组中。

//修改职工
void WorkerManager::mod_Emp()
{
    if (this->m_FileIsEmpty)
    {
        cout << "文件不存在或记录为空!" << endl;
    }
    else
    {
        cout << "请输入修改的职工编号:" << endl;
        int id;
        cin >> id;
        int ret = this->isExit(id);
        if (ret != -1)
        {
            //查找到编号的职工
            delete this->m_EmpArray[ret];

            int newId = 0;
            string newName = "";
            int dSelect = 0;

            cout << "查找到:" << id << "号职工,请输入新职工编号:" << endl;
            cin >> id;

            cout << "请输入姓名:" << endl;
            cin >> newName;

            cout << "请输入新的岗位:" << endl;
            cin >> dSelect;

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

            //更新数据到数组中
            this->m_EmpArray[ret] = worker;
            cout << "修改成功!" << endl;
            this->save();
        }
        else
        {
            cout << "查无此人!" << endl;
        }
    }
    system("pause");
    system("cls");
}

测试:

当前系统中保存了三个员工信息
查看
我们试着修改1号员工
要修改的员工不存在

会提示我们“查无此人!”。

我们再来修改2号员工,将姓名由“李四”修改为“张全蛋”。
要修改的员工存在
提示我们修改成功。我们来查看一下:
修改成功

再来看看文件里面的内容:
worker.txt
可以看到,文件内容也同步更新了。

查找职工

我们提供两种方式来查找职工:按照编号查询和按照姓名查找。按照姓名查找要查出所有的同名的信息出来
在WorkerManager中添加void find_Emp();函数

    //查找职工
    void find_Emp();

在WorkerManager.cpp中实现

//查找职工
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 ret = this->isExit(id);
            if (ret != -1)
            {
                //找到职工
                cout << "查找成功!该职工信息如下" << endl;
                this->m_EmpArray[ret]->showInfo();
            }
            else
            {
                cout << "查无此人!" << endl;
            }
        }
        else if (select == 2)
        {
            //按照姓名查找
            string name;
            cout << "请输入查找的姓名:" << endl;
            cin >> name;

            bool flag = false; //判断是否查找到 默认没有查到
            for (int i = 0; i < m_EmpNum; i++)
            {
                if (this->m_EmpArray[i]->m_Name == name)
                {
                    flag = true;
                    cout << "查找成功!职工编号为" << this->m_EmpArray[i]->m_ID << "的员工信息如下:" << endl;
                    this->m_EmpArray[i]->showInfo();
                }
            }
            if(flag==false)
            {
                cout << "查无此人!" << endl;
            }
        }
        else
        {
            cout << "输入有误!" << endl;
        }
    }

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

测试

  • 按工号查找:
  1. 查找的员工存在
    查找的员工存在
  2. 查找的员工不存在
    查找的员工不存在
  • 按姓名查找
    我们在我文件里手动加入一个名为“张全蛋”的员工,用于检测按照姓名查找时聪明的情况。
  1. 查找的人存在
    查找的人存在
  2. 查找的人不存在
    查找的人不存在

    测试结果与预期一致。

排序

采用选足择排序的思路,提供按职工工号排序的方式,可以进行升序和降序排序,并显示出来。

在WorkerManager类中添加成员函数void sort_Emp();

     //排序
    void sort_Emp();

在WorkerManager.cpp中实现

//排序
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 < this->m_EmpNum; j++)
            {
                if (select == 1) //升序
                {
                    if (this->m_EmpArray[i]->m_ID > this->m_EmpArray[j]->m_ID)
                    {
                        minOrMax = j;
                    }
                }
                else //降序
                {
                    if (this->m_EmpArray[i]->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();//排序后显示所有职工   
    }
}

测试

我们在网文件里手动添加两个员工数据,用于测试排序函数。添加后文件内容如下:
worker.txt
  • 升序
    升序
  • 降序
    降序
  • 文件为空

    下面我们把文件内容清空,再来做一个测试:
    文件为空

    测试结果于预期一致。

清空数据

清空数据要给用户一个后悔的语余地,一旦清空数据,就再也找不回来了,所以要有一个再次确认的操作。

在WorkerManager类中添加一个成员函数void claen_File();

    //清空文件
    void claen_File();

在头文件中实现该成员函数。清空的时候不能仅仅把文件清空,要把内存中开辟的所有空间都要清空。与析构函数类似,要先清空数组中每个指针维护的对象,然后在清空数据组。才算彻底清空。

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

    int select = 0;
    cin >> select;

    if (select == 1)
    {
        //清空文件
        ofstream ofs(FILE_NAME, ios::trunc);
        ofs.close();
        if (this->m_EmpArray != NULL)
        {
            //删除堆区每一个职工对象
            for (int i = 0; i < this->m_EmpNum; i++)
            {
                delete this->m_EmpArray[i];
                this->m_EmpArray[i] = NULL;
            }

            delete[] this->m_EmpArray;
            this->m_EmpArray = NULL;
            this->m_EmpNum = 0;         //人数清零
            this->m_FileIsEmpty = true; //文件为空标志为空
        }

        cout << "清空成功!" << endl;
    }

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

测试

我们先来看一下文件内容:
worker.txt

清空文件:
清空文件
再来查看一下:
查看

可以看到清空成功了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容