基于c/c++的公司职工管理系统软件的二次开发

引言:
经过在网络上的广泛搜索和比较,我了解了一款基于C/C++的公司职工管理系统软件,这款软件在基本功能方面表现相当完善,能够满足日常的使用需求。然而,在实际使用过程中,我也发现它存在一些问题和不足,所以我决定对该软件进行二次开发。
原始代码:

点击查看代码
**main.cpp**
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

#include "EmployeeManager.h"

int main() {
    EmployeeManager manager;
    int choice;
    while (true) {
    	manager.show_menu();
        cin >> choice;
        switch (choice) {
        case 1:
            manager.AddEmployee();
            break;
        case 2:
            manager.DeleteEmployee();
            break;
        case 3:
            manager.UpdateEmployee();
            break;
        case 4:
            manager.reseachStudentByName();
            break;
        case 5:
            manager.reseachStudentByOffice();
            break;
        case 6:
            manager.avgsalary();
            break;
        case 7:
            manager.exitsystem();
        default:
            cout << "输入有误,请重新选择" << endl;
            break;
        }
        system("pause");
		system("cls"); 
    }
    return 0;
}
**EmployeeManager.h**
#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

#include "Employee.h" 

#define EMPLOYEEFILE "employee.txt"

class EmployeeManager {
	private:
	    Employee* employees;   // 存储所有职工信息的数组
	    int count;             // 记录当前职工数
	    int capacity;          // 数组容量(最大职工数)
	public:
	    EmployeeManager();
	    ~EmployeeManager();
	    void show_menu();//菜单 
	    void AddEmployee();// 添加职工信息
	    void DeleteEmployee();	    // 删除职工信息
	    void UpdateEmployee();	 // 修改职工信息
	    void reseachStudentByName();// 按姓名查询职工信息
	    void reseachStudentByOffice();// 按科室查询职工信息
	    void avgsalary();// 统计平均工资
	    void SaveInfo();// 保存职工信息到文件
	    void expand();	// 扩容(double)
	    void loadFromFile();	// 从文件中加载职工信息
	    void exitsystem();
};
**EmployeeManager.cpp**
#include "EmployeeManager.h"

EmployeeManager::EmployeeManager() {
    employees = new Employee[10];   // 初始数组长度为10
    count = 0;
    capacity = 10;
    loadFromFile();
}

EmployeeManager::~EmployeeManager() {
    delete[] employees;   // 释放内存
}

void EmployeeManager::show_menu(){
	cout << "*****欢迎使用公司职工管理系统*****"<<endl;
	cout << "*      请选择需要进行的操作:    *" << endl;
    cout << "*        1.添加职工信息          *" << endl;
    cout << "*        2.删除职工信息          *" << endl;
    cout << "*        3.修改职工信息          *" << endl;
    cout << "*        4.按姓名查询职工信息    *" << endl;
    cout << "*        5.按科室查询职工信息    *" << endl;
    cout << "*        6.按科室统计平均工资    *" << endl;
    cout << "*        7.退出系统              *" << endl;
    cout << "**********************************" << endl;
} 

void EmployeeManager::AddEmployee() {
    if (count == capacity) {
        expand();   // 扩容后添加
    }
    int id_;
    string name_, sex_, phone_, office_;
    float salary_;
    cout << "请输入新员工信息:" << endl;
    cout << "工号:";
    cin >> id_;
    while (cin.fail()) {   // 输入错误处理
        cin.clear();
        cin.ignore();
        cout << "请输入工号:" << endl;
        cin >> id_;
    }
    for (int i = 0; i < count; i++) {// 检查工号是否已存在
        if (employees[i].id == id_) {
            cout << "工号已存在,请重新输入:" << endl;
            cin >> id_;
            i = -1;   // 重新循环开始检查
        }
    }
    cout << "请输入姓名:";
    cin >> name_;
    cout << "请输入性别:";
    cin >> sex_;
    cout << "请输入电话:";
    cin >> phone_;
    cout << "请输入科室(其中包含 办公室,技术部,市场部,财务部,人事部):";
    cin >> office_;
    cout << "请输入工资:";
    cin >> salary_;
    while (cin.fail()) {   // 输入错误处理
        cin.clear();
        cin.ignore();
        cout << "请输入正确的工资:" << endl;
        cin >> salary_;
    }
    employees[count] = Employee(id_, name_, sex_, phone_, office_, salary_);
    count++;
    SaveInfo();
    cout << "添加成功!" << endl;
}

void EmployeeManager::DeleteEmployee() {
    if (count == 0) {
        cout << "目前系统内没有员工信息" << endl;
        return;
    }
    int id_;
    cout << "请输入要删除的员工工号:" << endl;
    cin >> id_;
    for (int i = 0; i < count; i++) {   // 遍历数组查找
        if (employees[i].id == id_) {
            for (int j = i; j < count - 1; j++) {   // 删除并移动数组
                employees[j] = employees[j + 1];
            }
            count--;
            SaveInfo();
            cout << "删除成功!" << endl;
            return;
        }
    }
    cout << "未找到该员工信息" << endl;
}

void EmployeeManager::UpdateEmployee() {
    if (count == 0) {
        cout << "目前系统内没有员工信息" << endl;
        return;
    }
    int id_;
    cout << "请输入要修改的员工工号:" << endl;
    cin >> id_;
    for (int i = 0; i < count; i++) {   // 遍历数组查找
        if (employees[i].id == id_) {
            string name_, sex_, phone_, office_;
            float salary_;
            cout << "请输入修改后的姓名(原名字:"<<employees[i].name<<"):";
            cin >> name_;
            cout << "请输入修改后的性别(原性别:"<<employees[i].sex<<"):";
            cin >> sex_;
            cout << "请输入修改后的电话(原电话:"<<employees[i].phone<<"):";
            cin >> phone_;
            cout << "请输入修改后的科室(原科室:"<<employees[i].office<<"):";
            cin >> office_;
            cout << "请输入修改后的工资(原工资:"<<employees[i].salary<<"):";
            cin >> salary_;
            while (cin.fail()) {   // 输入错误处理
                cin.clear();
                cin.ignore();
                cout << "请输入正确的工资:" << endl;
                cin >> salary_;
            }
            employees[i].name = name_;
            employees[i].sex = sex_;
            employees[i].phone = phone_;
            employees[i].office = office_;
            employees[i].salary = salary_;
            SaveInfo();
            cout << "修改成功!" << endl;
            return;
        }
    }
    cout << "未找到该员工信息" << endl;
}

void EmployeeManager::reseachStudentByName() {
    if (count == 0) {
        cout << "目前系统内没有员工信息" << endl;
        return;
    }
    string name_;
    cout << "请输入要查找的员工姓名:" << endl;
    cin >> name_;
    bool found = false;
    for (int i = 0; i < count; i++) {   // 遍历数组查找
        if (employees[i].name == name_) {
            employees[i].show_data();
            found = true;
        }
    }
    if (!found) {
        cout << "未找到该员工信息" << endl;
    }
}

void EmployeeManager::reseachStudentByOffice() {
    if (count == 0) {
        cout << "目前系统内没有员工信息" << endl;
        return;
    }
    string office_;
    cout << "请输入要查找的员工科室:" << endl;
    cin >> office_;
    bool found = false;
    for (int i = 0; i < count; i++) {
        if (employees[i].office == office_) {
            employees[i].show_data();
            found = true;
        }
    }
    if (!found) {
        cout << "未找到该科室的员工信息" << endl;
    }
}

void EmployeeManager::avgsalary() {
    if (count == 0) {
        cout << "目前系统内没有员工信息" << endl;
        return;
    }
    string offices[] = { "办公室", "人事部","技术部", "财务部" , "市场部"};
    float salaries[] = {0, 0, 0, 0, 0};
    int counts[] = { 0, 0, 0, 0, 0 };
    for(int i = 0;i<count;i++){
    	for(int j = 0;j<5;j++){
    		if(employees[i].get_office() == offices[j]){
                salaries[j] += employees[i].get_salary();
                counts[j]++;
			}
		}
	}
    cout << "统计结果如下:" << endl;
    cout <<  left << setw(15) <<"科室名称"<< setw(15)<<"总人数"<< setw(15)<<"平均工资" << endl;
    for (int i = 0; i < 5; i++) {
        if (counts[i] == 0) continue;
        float avgsalary = salaries[i] / counts[i];
        cout <<left << setw(15)<< offices[i] <<setw(15)<<counts[i]<<setw(15)<< avgsalary << endl;
    }
}

void EmployeeManager::expand() {
    capacity *= 2;
    Employee* newArray = new Employee[capacity];
    for (int i = 0; i < count; i++) {
        newArray[i] = employees[i];
    }
    delete[] employees;
    employees = newArray;
}

void EmployeeManager::loadFromFile() {
	ifstream ifs;
	ifs.open(EMPLOYEEFILE, ios::in);
    if (!ifs) {
        return;
    }
    int id_;
    string name_, sex_, phone_, office_;
    float salary_;
    while (ifs >> id_ >> name_ >> sex_ >> phone_ >> office_ >> salary_) {   // 从文件中读取职工信息
        employees[count] = Employee(id_, name_, sex_, phone_, office_, salary_);
        count++;
    }
    ifs.close();
}

void EmployeeManager::SaveInfo() {
    ofstream ofs;
	ofs.open(EMPLOYEEFILE, ios::out);
    for (int i = 0; i < count; i++) {   // 将职工信息写入文件
        ofs << employees[i].id << " " << employees[i].name << " " << employees[i].sex << " " << employees[i].phone << " " << employees[i].office << " " << employees[i].salary << endl;
    }
    ofs.close();
} 

void EmployeeManager::exitsystem(){
	exit(0);
}
**employee.h**
#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;

class Employee {
	public:
	    int id;           // 工号
	    string name;      // 姓名
	    string sex;       // 性别
	    string phone;     // 电话
	    string office;    // 所在科室
	    float salary;     // 工资
    	Employee();
    	Employee(int id_, string name_, string sex_, string phone_, string office_, float salary_);
    	void show_data();
    	string get_office();
    	float get_salary();
};
**Employee.cpp**
#include "Employee.h"

Employee::Employee(){
	id = 0;
	name = "";
	sex = ""; 
	phone = ""; 
	office = ""; 
	salary = 0;
}

Employee::Employee(int id_, string name_, string sex_, string phone_, string office_, float salary_){
	id = id_;
    name = name_;
    sex = sex_;
    phone = phone_;
    office = office_;
    salary = salary_;
}

void Employee::show_data(){
	cout << "工号:" << id << "\t姓名:" << name << "\t性别:" << sex << "\t电话:" << phone << "\t科室:" << office << "\t工资:" << salary << endl;
}

string Employee::get_office(){
	return office;
}

float Employee::get_salary(){
	return salary;
}

程序主页面

以下是我对该软件的二次开发:
1.添加一个登录密码的界面。
  原因:考虑到这款软件作为一个公司职工管理系统,其安全性是至关重要的。为了确保只有授权人员能够访问和操作职工信息,我计划为其增加一个登录密码界面。这样一来,没有相应权限的人员将无法进入系统,从而有效防止了信息泄露和误操作的风险。通过这一改进,我们不仅能够提升系统的安全性,还能为公司职工信息提供更加可靠的保障。
  该密码验证我是用MD5加盐加密进行验证,输入的密码进行加密后和正确的密码的密文进行匹对。
md5加密代码

点击查看代码
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>

using namespace std;

#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476

const char str16[] = "0123456789abcdef";

const unsigned int T[] = {
    0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
    0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
    0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
    0x6b901122,0xfd987193,0xa679438e,0x49b40821,
    0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
    0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
    0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
    0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
    0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
    0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
    0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
    0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
    0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
    0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
    0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
    0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 };

const unsigned int s[] = { 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
                           5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
                           4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
                           6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21};
class MD5 {
private:
    unsigned int tempA, tempB, tempC, tempD, strlength;
public:
	string rightPass = "2ee2e1729baf76c0f6e81a7d04a0f435";
    MD5() {
        tempA = A;
        tempB = B;
        tempC = C;
        tempD = D;
        strlength = 0;
    }
    // F函数
    unsigned int F(unsigned int b, unsigned int c, unsigned int d) {
        return (b & c) | ((~b) & d);
    }
    // G函数
    unsigned int G(unsigned int b, unsigned int c, unsigned int d) {
        return (b & d) | (c & (~d));
    }
    // H函数
    unsigned int H(unsigned int b, unsigned int c, unsigned int d) {
        return b ^ c ^ d;
    }
    // I函数
    unsigned int I(unsigned int b, unsigned int c, unsigned int d) {
        return c ^ (b | (~d));
    }
    // 移位操作函数
    unsigned int shift(unsigned int a, unsigned int n) {
        return (a << n) | (a >> (32 - n));
    }
    // 编码函数
    string encode(string src) {
        vector<unsigned int> rec = padding(src);
        for(unsigned int i = 0; i < strlength/16; i++) {
            unsigned int num[16];
            for(int j = 0; j < 16; j++) {
                num[j] = rec[i*16+j];
            }
            iterateFunc(num, 16);
        }
        return format(tempA) + format(tempB) + format(tempC) + format(tempD);
    }
    // 循环压缩
    void iterateFunc(unsigned int* X, int size = 16) {
        unsigned int a = tempA,
                     b = tempB,
                     c = tempC,
                     d = tempD,
                     rec = 0,
                     g, k;
        for(int i = 0; i < 64; i++) {
            if(i < 16) {
                // F迭代
                g = F(b, c, d);
                k = i;
            }
            else if(i < 32) {
                // G迭代
                g = G(b, c, d);
                k = (1 + 5*i) % 16;
            }
            else if(i < 48) {
                // H迭代
                g = H(b, c, d);
                k = (5 + 3*i) % 16;
            }
            else {
                // I迭代
                g = I(b, c, d);
                k = (7*i) % 16;
            }
            rec = d;
            d = c;
            c = b;
            b = b + shift(a + g + X[k] + T[i], s[i]);
            a = rec;
        }
        tempA += a;
        tempB += b;
        tempC += c;
        tempD += d;
    }
    // 填充字符串
    vector<unsigned int> padding(string src) {
        // 以512位,64个字节为一组
        unsigned int num = ((src.length() + 8) / 64) + 1;
        vector<unsigned int> rec(num*16);
        strlength = num*16;
        for(unsigned int i = 0; i < src.length(); i++){
            // 一个unsigned int对应4个字节,保存4个字符信息
            rec[i>>2] |= (int)(src[i]) << ((i % 4) * 8);
        }
        // 补充1000...000
        rec[src.length() >> 2] |= (0x80 << ((src.length() % 4)*8));
        // 填充原文长度
        rec[rec.size()-2] = (src.length() << 3);
        return rec;
    }
    // 整理输出
    string format(unsigned int num) {
        string res = "";
        unsigned int base = 1 << 8;
        for(int i = 0; i < 4; i++) {
            string tmp = "";
            unsigned int b = (num >> (i * 8)) % base & 0xff;
            for(int j = 0; j < 2; j++) {
                tmp = str16[b%16] + tmp;
                b /= 16;
            }
            res += tmp;
        }
        return res;
    }
};



修改后main.cpp代码

点击查看代码
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <string.h>

using namespace std;

#include "EmployeeManager.h"
#include "function.h"


int main() {
	while(true){
		cout<<"请输入管理员密码:"<<endl;
		MD5 jiami;
		string enterPass;
		cin >> enterPass;
		string enterPass1 = jiami.encode(jiami.encode(enterPass)+enterPass);
		if(enterPass1 == jiami.rightPass){
			cout<<"密码正确"<<endl;
				        system("pause");
			system("cls"); 
				    EmployeeManager manager;
	    int choice;
	    while (true) {
	    	manager.show_menu();
	        cin >> choice;
	        switch (choice) {
	        case 1:
	            manager.AddEmployee();
	            break;
	        case 2:
	            manager.DeleteEmployee();
	            break;
	        case 3:
	            manager.UpdateEmployee();
	            break;
	        case 4:
	            manager.reseachStudentByName();
	            break;
	        case 5:
	            manager.reseachStudentByOffice();
	            break;
	        case 6:
	            manager.avgsalary();
	            break;
	        case 7:
	            manager.exitsystem();
	        default:
	            cout << "输入有误,请重新选择" << endl;
	            break;
	        }
	        system("pause");
			system("cls"); 
	    }

		} 
		else{
			cout<< "密码错误,请重新输入"<<endl;
			system("pause");
			system("cls"); 
		}
	}

    return 0;
}

**2. **对用户输入信息检验是否有效。
原代码 cout << "请输入姓名:"; cin >> name_; cout << "请输入性别:"; cin >> sex_; cout << "请输入电话:"; cin >> phone_; cout << "请输入科室(其中包含 办公室,技术部,市场部,财务部,人事部):"; cin >> office_;均没有检验数据是否正确,这难免造成小错误或者记录数据不正确
修改后代码

点击查看代码
   // 输入姓名
    do {  
        cout << "请输入姓名:";  
        cin >> name_;  
        if (name_.empty()) {  
            cout << "姓名不能为空,请重新输入!" << endl;  
        }  
    } while (name_.empty());  
    // 输入性别
    do {  
        cout << "请输入性别:";  
        cin >> sex_;  
        if (sex_ != "男" && sex_ != "女") {  
            cout << "性别必须为'男'或'女',请重新输入!" << endl;  
        }  
    } while (sex_ != "男" && sex_ != "女");  
    // 输入电话
    do {  
        cout << "请输入电话:";  
        cin >> phone_;  
        if(phone_.size() != 11){
        	cout<<"手机号输入不正确"<<endl;
		}
        // 这里可以根据电话号码的规则进行更复杂的检验,例如检查是否只包含数字  
        if (phone_.empty()) {  
            cout << "电话不能为空,请重新输入!" << endl;  
        }  
    } while (phone_.empty()||phone_.size() != 11);  
    // 输入科室
    string validOffices[] = {"办公室", "技术部", "市场部", "财务部", "人事部"}; 
	bool isValidOffice = false;   
    do {  
        cout << "请输入科室(其中包含 办公室,技术部,市场部,财务部,人事部):";  
        cin >> office_; 
        for (int i=0;i<5;i++) {  
            if (office_ == validOffices[i]) {  
                isValidOffice = true;  
                break;  
            }  
        }  
        if (!isValidOffice) {  
            cout << "科室输入无效,请输入:办公室,技术部,市场部,财务部,人事部中的一个!" << endl;  
        }  
    } while (!isValidOffice); 

运行结果
其他问题
该软件在可视化和数据存储方面存在明显不足。目前,整个系统主要依赖菜单形式进行展示,并且数据被不安全地存储在txt文件中。最初,我计划使用Java GUI和MySQL数据库来提升管理员体验和数据安全性,但由于技术和时间上的限制,二次开发工作未能顺利继续。若条件允许,我将不遗余力地继续推进该软件的二次开发,以优化用户界面和数据存储方式,确保软件的稳定性和安全性。
二次开发心得
经过对公司职工管理系统软件的二次开发实践,我深刻体会到,模块化设计和详尽的代码注释对于软件后期的维护、扩展以及性能提升具有决定性的作用。同时,我也意识到,无论是对外还是对内使用的软件,用户输入的安全性都是不容忽视的。为了防止输入渗透,我们必须严格限制输入的范围,并采取有效措施确保数据存储的安全。在满足软件功能需求的基础上,我们还应致力于持续优化用户界面,提升可视化布局和美化程度,以提供更加友好、直观的用户体验。

二次开发流程图

posted @ 2024-03-05 17:00  盗梦者17  阅读(64)  评论(0)    收藏  举报