c语言设计职工信息管理系统

99ANYc3cd6
预计阅读时长 49 分钟
位置: 首页 C语言 正文
  1. 添加职工信息:包括工号、姓名、性别、年龄、工资等。
  2. 显示所有职工信息:以表格形式展示所有已存储的职工。
  3. 查找职工信息:可以通过工号或姓名进行查找。
  4. 修改职工信息:根据工号找到职工并修改其信息。
  5. 删除职工信息:根据工号删除职工记录。
  6. 数据排序:可以按工资或年龄进行排序。
  7. 数据保存与加载:将数据从文件读取到内存,并将内存中的数据保存到文件,实现数据持久化。

设计思路

  1. 数据结构

    c语言设计职工信息管理系统
    (图片来源网络,侵删)
    • 使用 struct 来定义职工的数据结构,包含所需的各种信息。
    • 使用一个结构体数组 struct Employee emp[MAX] 来在内存中存储所有职工信息。MAX 是一个宏,定义最大职工数量。
    • 使用一个全局变量 int count 来记录当前系统中职工的实际数量。
  2. 模块化设计

    • 将每个功能(如添加、显示、查找等)都封装成一个独立的函数。
    • 编写一个主菜单函数 menu() 来显示操作选项,并根据用户的选择调用相应的功能函数,这使 main 函数非常简洁,易于维护。
  3. 文件操作

    • 使用 fopen, fread, fwrite, fclose 等标准C库函数进行文件读写。
    • 在程序启动时,尝试从一个文件(如 employees.dat)中加载数据。
    • 在每次对数据进行修改(添加、删除、修改)后,将整个数据数组重新写回文件,确保数据不丢失。

完整代码实现

下面是完整的C语言代码,你可以直接复制到一个 .c 文件中(employee_management.c)进行编译和运行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h> // 用于 getch(),在Windows下按任意键继续
#include <ctype.h> // 用于 toupper()
// 定义最大职工数量
#define MAX 1000
// 职工结构体
struct Employee {
    int id;         // 工号
    char name[50];  // 姓名
    char gender[10];// 性别
    int age;        // 年龄
    float salary;   // 工资
};
// 全局变量
struct Employee emp[MAX]; // 职工数组
int count = 0;            // 当前职工数量
// 函数声明
void menu();
void addEmployee();
void displayEmployees();
void searchEmployee();
void modifyEmployee();
void deleteEmployee();
void sortEmployees();
void saveToFile();
void loadFromFile();
void clearInputBuffer();
int main() {
    loadFromFile(); // 程序启动时加载数据
    menu();
    return 0;
}
// 显示主菜单
void menu() {
    int choice;
    while (1) {
        system("cls"); // Windows下清屏,Linux/macOS用 system("clear");
        printf("\n\n");
        printf("========================================\n");
        printf("=     职工信息管理系统 v1.0           =\n");
        printf("========================================\n");
        printf("=   1. 添加职工信息                   =\n");
        printf("=   2. 显示所有职工信息               =\n");
        printf("=   3. 查找职工信息                   =\n");
        printf("=   4. 修改职工信息                   =\n");
        printf("=   5. 删除职工信息                   =\n");
        printf("=   6. 职工信息排序                   =\n");
        printf("=   0. 退出系统                       =\n");
        printf("========================================\n");
        printf("请输入您的选择 (0-6): ");
        if (scanf("%d", &choice) != 1) {
            printf("输入无效,请输入数字!\n");
            clearInputBuffer();
            getch();
            continue;
        }
        clearInputBuffer(); // 清除输入缓冲区中的换行符等
        switch (choice) {
            case 1:
                addEmployee();
                break;
            case 2:
                displayEmployees();
                break;
            case 3:
                searchEmployee();
                break;
            case 4:
                modifyEmployee();
                break;
            case 5:
                deleteEmployee();
                break;
            case 6:
                sortEmployees();
                break;
            case 0:
                saveToFile(); // 退出前保存数据
                printf("\n感谢使用,系统已退出!\n");
                exit(0);
            default:
                printf("\n无效的选择,请重新输入!\n");
        }
        printf("\n按任意键返回主菜单...");
        getch();
    }
}
// 添加职工信息
void addEmployee() {
    if (count >= MAX) {
        printf("\n职工数量已达上限,无法添加!\n");
        return;
    }
    system("cls");
    printf("\n--- 添加职工信息 ---\n");
    struct Employee e;
    printf("请输入工号: ");
    scanf("%d", &e.id);
    clearInputBuffer();
    // 检查工号是否已存在
    for (int i = 0; i < count; i++) {
        if (emp[i].id == e.id) {
            printf("\n错误:该工号已存在!\n");
            return;
        }
    }
    printf("请输入姓名: ");
    fgets(e.name, sizeof(e.name), stdin);
    e.name[strcspn(e.name, "\n")] = 0; // 去掉fgets读取的换行符
    printf("请输入性别: ");
    fgets(e.gender, sizeof(e.gender), stdin);
    e.gender[strcspn(e.gender, "\n")] = 0;
    printf("请输入年龄: ");
    scanf("%d", &e.age);
    clearInputBuffer();
    printf("请输入工资: ");
    scanf("%f", &e.salary);
    clearInputBuffer();
    emp[count++] = e; // 将新职工加入数组,并增加计数
    printf("\n职工信息添加成功!\n");
}
// 显示所有职工信息
void displayEmployees() {
    if (count == 0) {
        printf("\n系统中没有职工信息!\n");
        return;
    }
    system("cls");
    printf("\n--- 所有职工信息 ---\n");
    printf("-----------------------------------------------------------------\n");
    printf("| %-10s | %-15s | %-8s | %-6s | %-10s |\n", "工号", "姓名", "性别", "年龄", "工资");
    printf("-----------------------------------------------------------------\n");
    for (int i = 0; i < count; i++) {
        printf("| %-10d | %-15s | %-8s | %-6d | %-10.2f |\n", 
               emp[i].id, emp[i].name, emp[i].gender, emp[i].age, emp[i].salary);
    }
    printf("-----------------------------------------------------------------\n");
}
// 查找职工信息
void searchEmployee() {
    if (count == 0) {
        printf("\n系统中没有职工信息!\n");
        return;
    }
    system("cls");
    printf("\n--- 查找职工信息 ---\n");
    int option;
    printf("1. 按工号查找\n");
    printf("2. 按姓名查找\n");
    printf("请选择查找方式 (1-2): ");
    scanf("%d", &option);
    clearInputBuffer();
    if (option == 1) {
        int id;
        printf("请输入要查找的工号: ");
        scanf("%d", &id);
        clearInputBuffer();
        int found = 0;
        for (int i = 0; i < count; i++) {
            if (emp[i].id == id) {
                found = 1;
                printf("\n找到职工信息:\n");
                printf("-----------------------------------------------------------------\n");
                printf("| %-10s | %-15s | %-8s | %-6s | %-10s |\n", "工号", "姓名", "性别", "年龄", "工资");
                printf("-----------------------------------------------------------------\n");
                printf("| %-10d | %-15s | %-8s | %-6d | %-10.2f |\n", 
                       emp[i].id, emp[i].name, emp[i].gender, emp[i].age, emp[i].salary);
                printf("-----------------------------------------------------------------\n");
                break;
            }
        }
        if (!found) {
            printf("\n未找到工号为 %d 的职工!\n", id);
        }
    } else if (option == 2) {
        char name[50];
        printf("请输入要查找的姓名: ");
        fgets(name, sizeof(name), stdin);
        name[strcspn(name, "\n")] = 0;
        int found = 0;
        printf("\n查找结果:\n");
        printf("-----------------------------------------------------------------\n");
        printf("| %-10s | %-15s | %-8s | %-6s | %-10s |\n", "工号", "姓名", "性别", "年龄", "工资");
        printf("-----------------------------------------------------------------\n");
        for (int i = 0; i < count; i++) {
            if (strstr(emp[i].name, name) != NULL) { // 使用strstr进行模糊查找
                found = 1;
                printf("| %-10d | %-15s | %-8s | %-6d | %-10.2f |\n", 
                       emp[i].id, emp[i].name, emp[i].gender, emp[i].age, emp[i].salary);
            }
        }
        if (!found) {
            printf("\n未找到姓名包含 \"%s\" 的职工!\n", name);
        }
        printf("-----------------------------------------------------------------\n");
    } else {
        printf("\n无效的选择!\n");
    }
}
// 修改职工信息
void modifyEmployee() {
    if (count == 0) {
        printf("\n系统中没有职工信息!\n");
        return;
    }
    system("cls");
    printf("\n--- 修改职工信息 ---\n");
    int id;
    printf("请输入要修改的职工工号: ");
    scanf("%d", &id);
    clearInputBuffer();
    for (int i = 0; i < count; i++) {
        if (emp[i].id == id) {
            printf("\n已找到该职工,请输入新的信息(不修改则直接回车):\n");
            char input[100];
            printf("姓名 [%s]: ", emp[i].name);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) { // 如果输入了内容
                input[strcspn(input, "\n")] = 0;
                strcpy(emp[i].name, input);
            }
            printf("性别 [%s]: ", emp[i].gender);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                input[strcspn(input, "\n")] = 0;
                strcpy(emp[i].gender, input);
            }
            printf("年龄 [%d]: ", emp[i].age);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                emp[i].age = atoi(input);
            }
            printf("工资 [%.2f]: ", emp[i].salary);
            fgets(input, sizeof(input), stdin);
            if (strlen(input) > 1) {
                emp[i].salary = atof(input);
            }
            printf("\n职工信息修改成功!\n");
            return;
        }
    }
    printf("\n未找到工号为 %d 的职工!\n", id);
}
// 删除职工信息
void deleteEmployee() {
    if (count == 0) {
        printf("\n系统中没有职工信息!\n");
        return;
    }
    system("cls");
    printf("\n--- 删除职工信息 ---\n");
    int id;
    printf("请输入要删除的职工工号: ");
    scanf("%d", &id);
    clearInputBuffer();
    for (int i = 0; i < count; i++) {
        if (emp[i].id == id) {
            // 将后面的所有元素前移一位
            for (int j = i; j < count - 1; j++) {
                emp[j] = emp[j + 1];
            }
            count--; // 职工总数减一
            printf("\n工号为 %d 的职工信息已删除!\n", id);
            return;
        }
    }
    printf("\n未找到工号为 %d 的职工!\n", id);
}
// 职工信息排序
void sortEmployees() {
    if (count == 0) {
        printf("\n系统中没有职工信息!\n");
        return;
    }
    system("cls");
    printf("\n--- 职工信息排序 ---\n");
    int option;
    printf("1. 按工资升序排序\n");
    printf("2. 按工资降序排序\n");
    printf("3. 按年龄升序排序\n");
    printf("4. 按年龄降序排序\n");
    printf("请选择排序方式 (1-4): ");
    scanf("%d", &option);
    clearInputBuffer();
    // 使用简单的冒泡排序
    for (int i = 0; i < count - 1; i++) {
        for (int j = 0; j < count - i - 1; j++) {
            int should_swap = 0;
            if (option == 1 && emp[j].salary > emp[j + 1].salary) should_swap = 1;
            if (option == 2 && emp[j].salary < emp[j + 1].salary) should_swap = 1;
            if (option == 3 && emp[j].age > emp[j + 1].age) should_swap = 1;
            if (option == 4 && emp[j].age < emp[j + 1].age) should_swap = 1;
            if (should_swap) {
                struct Employee temp = emp[j];
                emp[j] = emp[j + 1];
                emp[j + 1] = temp;
            }
        }
    }
    printf("\n排序完成!\n");
    displayEmployees(); // 排序后显示结果
}
// 将数据保存到文件
void saveToFile() {
    FILE *fp = fopen("employees.dat", "wb");
    if (fp == NULL) {
        printf("\n无法打开文件进行保存!\n");
        return;
    }
    // 一次写入整个结构体数组
    fwrite(emp, sizeof(struct Employee), count, fp);
    fclose(fp);
    printf("\n数据已成功保存到 employees.dat 文件!\n");
}
// 从文件加载数据
void loadFromFile() {
    FILE *fp = fopen("employees.dat", "rb");
    if (fp == NULL) {
        // 文件不存在是正常情况(首次运行)
        return;
    }
    // 一次读取整个结构体数组
    count = fread(emp, sizeof(struct Employee), MAX, fp);
    fclose(fp);
    printf("\n数据已成功从 employees.dat 文件加载!\n");
}
// 清除输入缓冲区
void clearInputBuffer() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

如何编译和运行

  1. 保存代码:将上面的代码保存为 employee_management.c
  2. 编译:打开终端或命令提示符,使用GCC进行编译。
    gcc employee_management.c -o employee_management
  3. 运行
    • 在 Windows 上:直接运行生成的 employee_management.exe 文件。
    • 在 Linux/macOS 上:在终端中运行 ./employee_management

注意

  • 代码中使用了 system("cls") 来清屏,这是Windows特有的,如果你在Linux或macOS上运行,需要将其改为 system("clear")
  • getch() 函数用于实现“按任意键继续”的功能,它包含在 <conio.h> 头文件中,这个头文件在标准C中不存在,但在Windows的编译器(如Visual Studio, MinGW)中可用,如果你在Linux/macOS上编译,需要用其他方法替代,printf("Press Enter to continue..."); getchar();
  • fgets() 用于安全地读取字符串,可以防止缓冲区溢出,读取后需要手动移除末尾的换行符 \n

功能演示简述

  1. 启动:程序会自动尝试从 employees.dat 加载数据。
  2. 添加:选择 1,按照提示输入职工信息,系统会检查工号是否重复。
  3. 显示:选择 2,以清晰的表格形式列出所有职工。
  4. 查找:选择 3,可以选择按工号精确查找或按姓名模糊查找。
  5. 修改:选择 4,输入工号后,可以逐项修改职工信息,不修改的项直接按回车即可。
  6. 删除:选择 5,输入工号,系统会找到并删除该职工,后面的职工信息会自动前移填补空缺。
  7. 排序:选择 6,可以按工资或年龄进行升序或降序排列。
  8. 退出:选择 0,系统会先将所有数据保存到 employees.dat 文件,然后退出,下次启动时,数据会自动恢复。

这个系统设计虽然使用了数组,对于超大规模数据(超过MAX)会不够用,但对于学习C语言和掌握基本的数据结构、文件操作、模块化编程思想来说,是一个非常经典和完整的示例。

-- 展开阅读全文 --
头像
C语言学生成绩管理系统如何实现核心功能?
« 上一篇 今天
织梦首页如何调用内容图片?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]