cpp C

Cpp职工管理系统

Posted by LemonWhale on May 20, 2024

一、管理系统需求

1.1 公司职工分类
  1. 普通职工:完成经理交给的任务
  2. 经理:完成老板交给的任务,并下任务给员工
  3. 老板:管理公司所有的事务
1.2 管理系统中需要实现的功能
  1. 退出管理程序:退出当前管理系统
  2. 增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为:职工编号、姓名、部门编号
  3. 显示职工信息:显示公司内部所有职工的信息
  4. 删除离职职工:按照编号删除指定的职工
  5. 修改职工信息:按照编号修改职工的个人信息
  6. 查找职工信息:按照职工的编号或者职工的姓名进行查找相关的人员信息
  7. 按照编号排序:按照职工编号,进行排序,排序规则由用户指定
  8. 清空所有文档:清空文件中记录的所有职工信息(需要二次确认)

    二、创建管理类

    • 管理类负责的内容如下:
    1. 与用户的沟通菜单页面
    2. 对职工的增删改查操作
    3. 与文件的读写交互
2.1 main函数
#include <iostream>
#include "workerManager.h"

int main() {
    workerManager wm;
    int choice = 0;//记录用户的选择  
	while (true) {  
	    wm.showMenu();  
	    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;  
	    }  
	}
    return 0;
}
2.2 workerManager.h
#pragma once
#include <iostream>
using namespace std;

class workerManager{
public:
    workerManager();
    ~workerManager();
};
2.3 workManager.cpp
#include "workerManager.h"  
  
workerManager::workerManager() {}  
workerManager::~workerManager() {}

三、菜单功能

  • 创建showMenu()函数
    3.1 workerManager.h
    void showMenu();
    
    3.2 workerManager.cpp
    void workerManager::showMenu() {
      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;
    }
    

    四、退出功能

  • 创建exitSystem()函数
    4.1 workerManager.h
    void exitSystem();
    
    4.2 workerManager.cpp
    void workerManager::exitSystem() {  
      cout << "欢迎下次使用!" << endl;  
      system("pause");  
      exit(0);  
    }
    

    五、创建职工类

  • 创建一个抽象职工类,具体职工类型继承抽象类
    5.1 建立抽象类文件 Worker.h

    ```Cpp #pragma once
    #include #include using namespace std;

// 创建Worker抽象类
class Worker {
public:
virtual void showInfo() = 0;
virtual string getDeptName() = 0;

int m_Id;  
string m_Name;  
int m_workerDeptId;   }; ``` ##### 5.2 创建普通员工类 ###### 5.2.1 头文件 ```Cpp #pragma once   #include <iostream>   #include <string>   using namespace std;   #include "Worker.h"  

class Employee : public Worker {
public:
Employee(int id, string name, int deptId);
void showInfo() override;
string getDeptName() override;
};

###### 5.2.2 Cpp源文件
```Cpp
#include "Employee.h"

Employee::Employee(int id, std::string name, int deptId) {
    m_Id = id;
    m_Name = name;
    m_workerDeptId = deptId;
}

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

string Employee::getDeptName() {
    return string("员工");
}
5.3 创建经理类
5.3.1 头文件
#pragma once  
#include <iostream>  
#include <string>  
using namespace std;  
#include "Worker.h"  
  
class Manager : public Worker {  
public:  
    Manager(int id, string name, int deptId);  
    void showInfo() override;  
    string getDeptName() override;  
};
5.3.2 Cpp源文件
#include "Manager.h"  
  
Manager::Manager(int id, std::string name, int deptId) {  
    m_Id = id;  
    m_Name = name;  
    m_workerDeptId = deptId;  
}  
  
void Manager::showInfo() {  
    cout << "编号:" << this->m_Id 
    << "\t姓名:" << this->m_Name 
    << "\t岗位:" << this->getDeptName() 
    << "\t职责:完成老板交给的任务,并下任务给员工" << endl;  
}  
  
string Manager::getDeptName() {  
    return string("经理");  
}
5.4 创建老板类
5.4.1 头文件
#pragma once  
#include <iostream>  
#include <string>  
using namespace std;  
#include "Worker.h"  
  
class Boss : public Worker {  
public:  
    Boss(int id, string name, int deptId);  
    void showInfo() override;  
    string getDeptName() override;  
};
5.4.2 Cpp源文件
#include "Boss.h"  
  
Boss::Boss(int id, std::string name, int deptId) {  
    m_Id = id;  
    m_Name = name;  
    m_workerDeptId = deptId;  
}  
  
void Boss::showInfo() {  
    cout << "编号:" << this->m_Id 
    << "\t姓名:" << this->m_Name 
    << "\t岗位:" << this->getDeptName() 
    << "\t职责:管理公司所有的事务" << endl;  
}  
  
string Boss::getDeptName() {  
    return string("老板");  
}

六、添加职工

6.1 功能分析
  • 功能描述:批量添加职工,并且保存到文件中
  • 如果想把所有种类的员工都放在一个数组中,可以将所有员工的指针维护到一个数组里;
  • 如果想在程序中维护这个不定长度的数组,可以将数组创建在堆区,并利用Worker**的指针维护
    6.2 功能实现

    ```Cpp void workerManager::exitSystem() { cout « “欢迎下次使用!” « endl; system(“pause”); exit(0); }

void workerManager::addWorker() { int addNum;

cout << "请输入要添加的员工的数量" << endl;

cin >> addNum;

if (addNum > 0) {
    // 新员工的人数
    int newSize = this->workerNum + addNum;

    // 为新加的员工开辟一块新空间
    // Worker ** 是一个二级指针,指向一个指向Worker的指针
    // new Worker *[newSize] 中的 Worker* 是表示数组中的每个元素都是一个Worker*的指针
    Worker **newSpace = new Worker *[newSize];

    // 将原空间中的元素放在新空间中
    if (workerArray != NULL) {
        for (int i = 0; i < workerNum; i++) {
            newSpace[i] = workerArray[i];
        }
    }

    // 输入新职工
    for (int i = 0; i < addNum; i++) {
        // 员工编号
        int id;
        // 员工姓名
        string name;
        // 员工部门
        int did;

        cout << " 请输入第 " << i + 1 
        << " 个新员工的员工编号: " << endl;
        // 判断员工id是否存在
        while (true) {
            cin >> id;
            int ret = this->IsExist(id);
            if (ret != -1) {
                cout << "该编号已经被占用,请重新输入:" << endl;
            }
            else {
                break;
            }
        }

        cout << " 请输入第 " << i + 1 
        << " 个新员工的姓名: " << endl;
        cin >> name;
        
        cout << " 请输入第 " << i + 1 
        << " 个新员工的部门编号: " << endl;
        cout << "1. 普通职员" << endl;
        cout << "2. 经理" << endl;
        cout << "3. 老板" << endl;
        cin >> did;

        // 创建一个抽象父类指针
        Worker *worker;

        // 使用多态创建不同类型的员工
        switch (did) {
        case 1:
            worker = new Employee(id, name, did);
            break;
        case 2:
            worker = new Manager(id, name, did);
            break;
        case 3:
            worker = new Boss(id, name, did);
            break;
        }

        newSpace[workerNum + i] = worker;
    }

    // 释放原来的内存
    delete[] this->workerArray;

    // 将指针指向新内存
    this->workerArray = newSpace;

    // 更新员工数量
    this->workerNum = newSize;

    // 保存文件到指定路径
    save();

    // 更新文件为空标志位
    this->m_FileIsEmpty = false;

    // 提示信息
    cout << "添加 " << addNum << " 个新员工成功" << endl;
}
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->workerNum; i++) {
          ofs << this->workerArray[i]->m_Id << " "
              << this->workerArray[i]->m_Name << " "
              << this->workerArray[i]->m_workerDeptId << endl;
      }
    
      // 关闭文件
      ofs.close();
    
      cout << "员工文件更新在:" << FILENAME << endl;
    }
    

    八、文件交互 - 读文件

    8.1 功能分析
  • 功能描述:将文件中的内容读取到程序中
  • 构造函数初始化分为三种情况:
    • 第一次使用,文件未创建
    • 文件存在,但是数据被用户清空
    • 文件存在,并且保存职工的所有数据
      8.2 功能实现
  • 读文件的功能都实现在workerManager的构造函数中
    8.1 文件未创建
    // 1、文件不存在  
    if (!ifs.is_open()) {  
      cout << "文件不存在" << endl;  
      
      // 员工人数置空  
      this->workerNum = 0;  
      
      // 员工数组置空  
      this->workerArray = NULL;  
      
      // 初始化文件为空标志位  
      this->m_FileIsEmpty = true;  
      
      ifs.close();  
      return;  
    }
    
    8.2 文件为空

    ```Cpp

// 2、文件存在但为空
char ch;
ifs » ch;
// ifs.eof()返回一个布尔值,若为真则为文件尾
if (ifs.eof()) {
cout « “文件为空” « endl;

// 员工人数置空  
this->workerNum = 0;  
  
// 员工数组置空  
this->workerArray = NULL;  
  
// 初始化文件为空标志位  
this->m_FileIsEmpty = true;  
  
ifs.close();  
return;   } ``` ###### 8.3 文件存在且不为空 1. 需要创建一个函数`getNum`获得文件中的员工个数
```Cpp
// 获取文件中员工的数量
int workerManager::getNum() {
    int num = 0;
    int id;
    string name;
    int dId;

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

    if (!ifs.is_open()) {
        cout << "文件打开异常" << endl;
        return -1;
    }

	// 使用流文件读取,空格为一个分隔符
    while (ifs >> id && ifs >> name && ifs >> dId) {
        num++;
    }

    return num;
}
``` 1. 将文件中的人员读取到维护的`workArray`数组中
```Cpp
// 从文件初始化员工列表
void workerManager::initWorker() {
    ifstream ifs;
    ifs.open(FILENAME, ios::in);
    if (!ifs.is_open()) {
        cout << "文件打开异常" << endl;
        return;
    }

    Worker *worker = NULL;

    int id;
    string name;
    int dId;

    int index = 0;

    // 读取文件
    while (ifs >> id && ifs >> name && ifs >> dId) {
        switch (dId) {
        case 1:
            worker = new Employee(id, name, dId);
            break; // 千万别忘了break!!!
        case 2:
            worker = new Manager(id, name, dId);
            break;
        case 3:
            worker = new Boss(id, name, dId);
            break;
        }
        this->workerArray[index++] = worker;
    }

    // 关闭文件
    ifs.close();
}
``` 1. 整合功能
```Cpp
// 3、文件存在且不为空
    else {
        cout << "现在的员工人数为:" << this->getNum() << endl;
        this->workerNum = this->getNum();
        this->m_FileIsEmpty = false;
        // 为员工列表开辟空间
        this->workerArray = new Worker *[this->workerNum];
        // 初始化员工列表
        initWorker();
        for (int i = 0; i < this->workerNum; i++) {
            cout << this->workerArray[i]->m_Name << endl;
        }
    }
``` ###### 8.4 初始化完毕 ```Cpp workerManager::workerManager() {
ifstream ifs;
ifs.open(FILENAME, ios::in);

// 1、文件不存在
if (!ifs.is_open()) {
    cout << "文件不存在" << endl;

    // 员工人数置空
    this->workerNum = 0;

    // 员工数组置空
    this->workerArray = NULL;

    // 初始化文件为空标志位
    this->m_FileIsEmpty = true;

    ifs.close();
    return;
}

// 2、文件存在但为空
char ch;
ifs >> ch;
// ifs.eof()返回一个布尔值,若为真则为文件尾
if (ifs.eof()) {
    cout << "文件为空" << endl;

    // 员工人数置空
    this->workerNum = 0;

    // 员工数组置空
    this->workerArray = NULL;

    // 初始化文件为空标志位
    this->m_FileIsEmpty = true;

    ifs.close();
    return;
}

// 3、文件存在且不为空
else {
    cout << "现在的员工人数为:" << this->getNum() << endl;
    this->workerNum = this->getNum();
    this->m_FileIsEmpty = false;
    // 为员工列表开辟空间
    this->workerArray = new Worker *[this->workerNum];
    // 初始化员工列表
    initWorker();
    for (int i = 0; i < this->workerNum; i++) {
        cout << this->workerArray[i]->m_Name << endl;
    }
} } ``` #### 九、显示职工 ```Cpp // 显示员工信息   void workerManager::showWorkers() {  
if (this->m_FileIsEmpty) {  
    cout << "员工列表为空" << endl;  
    system("pause");  
    system("cls");  
    return;  
}  
else {  
    for (int i = 0; i < this->workerNum; i++) {  
        this->workerArray[i]->showInfo();  
    }  
}  
  
system("pause");  
system("cls");   } ``` #### 十、删除职工 ##### 10.1 删除前先判断员工是否存在 ```Cpp // 判断员工是否存在 int workerManager::IsExist(int id) {
int index = -1;
for (int i = 0; i < this->workerNum; i++) {
    if (workerArray[i]->m_Id == id) {
        index = i;
        break;
    }
}
return index; } ``` ##### 10.2 删除员工,需要二次确认 ```Cpp // 删除员工 void workerManager::Del_Emp() {
if (this->m_FileIsEmpty) {
    cout << "文件为空" << endl;
    system("pause");
    return;
}

int id;
cout << "请输入要删除的员工Id:" << endl;
cin >> id;

int confirm = 0;
cout << "确认删除?(此操作不可撤销)" << endl;
cout << "1. 确认" << endl;
cout << "2. 取消" << endl;
cin >> confirm;

if (confirm == 1) {
    int ret = IsExist(id);
    if (ret != -1) {
        for (int i = ret; i < this->workerNum; i++) {
            this->workerArray[i] = this->workerArray[i + 1];
        }

        // 更新人数
        this->workerNum--;

        // 保存到文件
        this->save();

        // 输出提示信息
        cout << "删除成功" << endl;
    }
    else {
        cout << "查无此人" << endl;
        system("pause");
        system("cls");
        return;
    }
}
else {
    cout << "操作取消" << endl;
}

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

十一、修改职工

  • 修改职工前直接把原先的职工内存释放,再根据员工部门重新创建
    // 修改员工信息
    void workerManager::Mod_Emp() {
      if (this->m_FileIsEmpty) {
          cout << "文件为空" << endl;
          return;
      }
    
      int id;
      cout << "请输入要修改的员工Id:" << endl;
      cin >> id;
    
      int ret = IsExist(id);
      if (ret != -1) {
          delete this->workerArray[ret];
    
          int newID;
          string newName;
          int newDId;
    
          cout << "请输入此员工修改后的id:" << endl;
          cin >> newID;
    
          cout << "请输入此员工修改后的姓名:" << endl;
          cin >> newName;
    
          cout << "请输入此员工修改后的部门编号:" << endl;
          cin >> newDId;
    
          Worker *worker = NULL;
          switch (newDId) {
          case 1:
              worker = new Employee(newID, newName, newDId);
              break; // 千万别忘了break!!!
          case 2:
              worker = new Manager(newID, newName, newDId);
              break;
          case 3:
              worker = new Boss(newID, newName, newDId);
              break;
          }
          this->workerArray[ret] = worker;
      }
    
      // 保存文件
      this->save();
    }
    

    十二、查找职工

  • 功能:根据id或者姓名查找员工
  • 根据姓名查找需要找到所有同名的员工
    // 使用id或者姓名查找员工
    void workerManager::Search_Emp() {
      if (this->m_FileIsEmpty) {
          cout << "文件为空" << endl;
          system("pause");
          system("cls");
          return;
      }
    
      int SChoice = 0;
      cout << "请输入你要查找的方式:" << endl;
      cout << "1. 按编号查找" << endl;
      cout << "2. 按姓名查找" << endl;
      cin >> SChoice;
    
      if (SChoice == 1) {
          int id;
          cout << "请输入要查找的员工Id:" << endl;
          cin >> id;
    
          int ret = IsExist(id);
          if (ret != -1) {
              this->workerArray[ret]->showInfo();
          }
          else {
              cout << "查无此人" << endl;
              system("pause");
              system("cls");
              return;
          }
      }
      // 按姓名查找需要查出所有同名的人
      else if (SChoice == 2) {
          string name;
          cout << "请输入要查找的员工姓名:" << endl;
          cin >> name;
    
          bool flag = false;
          for (int i = 0; i < this->workerNum; i++) {
              if (this->workerArray[i]->m_Name == name) {
                  flag = true;
                  this->workerArray[i]->showInfo();
              }
          }
          if (flag == false) {
              cout << "查无此人" << endl;
              return;
          }
      }
    
      system("pause");
      system("cls");
    }
    

    十三、排序

  • 功能:根据员工编号进行升序或者降序排列
    // 给员工排序
    void workerManager::Sort_Emp() {
      if (this->m_FileIsEmpty) {
          cout << "文件为空" << endl;
          system("pause");
          system("cls");
          return;
      }
    
      cout << "请选择排序方式:" << endl;
      cout << "1. 升序" << endl;
      cout << "2. 降序" << endl;
      int select;
      cin >> select;
    
      for (int i = 0; i < this->workerNum; i++) {
          int originMin = i;
          for (int j = i + 1; j < this->workerNum; j++) {
              if (select == 1) {
                  if (this->workerArray[originMin]->m_Id > this->workerArray[j]->m_Id) {
                      originMin = j;
                  }
              }
              else if (select == 2) {
                  if (this->workerArray[originMin]->m_Id < this->workerArray[j]->m_Id) {
                      originMin = j;
                  }
              }
              else {
                  cout << "您输入的排序方式有误" << endl;
                  return;
              }
          }
    
          if (originMin != i) {
              Worker *temp = workerArray[i];
              workerArray[i] = workerArray[originMin];
              workerArray[originMin] = temp;
          }
      }
    
      // 保存文件
      cout << "排序成功" << endl;
      this->save();
      this->showWorkers();
    }
    

    十四、清空文件

    14.1 清空文件操作
  • 功能:删除所有的员工信息
    // 清空员工信息  
    void workerManager::Clear_Emp() {  
      if (this->m_FileIsEmpty) {  
          cout << "文件为空" << endl;  
          system("pause");  
          system("cls");  
          return;  
      }  
      
      int comfirm = 0;  
      cout << "确认删除所有员工信息吗?(此操作不可撤回)" << endl;  
      cout << "1. 确认" << endl;  
      cout << "2. 取消" << endl;  
      cin >> comfirm;  
      
      if (comfirm == 1) {  
          ofstream ofs;  
          // trunc 重写覆盖  
          ofs.open(FILENAME, ios::trunc);  
          ofs.close();  
      
          if (this->workerArray != NULL) {  
              for (int i = 0; i < this->workerNum; i++) {  
                  if (workerArray[i] != NULL) {  
                      delete workerArray[i];  
                  }  
              }  
          }  
          delete[] this->workerArray;  
          this->workerNum = 0;  
          this->m_FileIsEmpty = true;  
      
          cout << "成功清除所有员工细信息" << endl;  
      }  
      else {  
          cout << "操作取消" << endl;  
      }  
      
      system("pause");  
      system("cls");  
    }
    
    14.2 workManager的析构函数
    workerManager::~workerManager() {  
      // 释放堆区内存  
      if (this->workerArray != NULL) {  
          for (int i = 0; i < this->workerNum; i++) {  
              if (workerArray[i] != NULL) {  
                  delete workerArray[i];  
              }  
          }  
          delete[] this->workerArray;  
      }  
    }
    

    十五、主程序

    ```Cpp #include “workerManager.h” #include using namespace std;

int main() { workerManager wm; int choice = 0; // 记录用户的选择 while (true) { wm.showMenu(); cout « “请输入您的选择:” « endl; cin » choice; switch (choice) { case 0: // 退出管理系统 wm.exitSystem(); break; case 1: // 增加职工信息 wm.addWorker(); break; case 2: // 显示职工信息 wm.showWorkers(); break; case 3: // 删除职工信息 wm.Del_Emp(); break; case 4: // 修改职工信息 wm.Mod_Emp(); break; case 5: // 查找职工信息 wm.Search_Emp(); break; case 6: // 按照编号排序 wm.Sort_Emp(); break; case 7: // 清空所有文档 wm.Clear_Emp(); break; default: system(“cls”); break; } } return 0; } ```