C语言职工信息管理系统课程设计
项目概述
本项目旨在使用C语言开发一个功能完善的职工信息管理系统,系统通过结构体来存储职工信息,利用文件进行数据的持久化存储,并提供了友好的命令行交互界面,用户可以方便地进行职工信息的增加、删除、修改、查询、排序和统计等操作。

(图片来源网络,侵删)
功能需求分析
系统应具备以下核心功能:
- 信息录入: 添加新职工的信息,包括工号、姓名、性别、年龄、学历、工资、入职日期等。
- 信息显示: 在屏幕上以表格形式列出所有职工的信息。
- 信息查询:
- 按工号精确查询。
- 按姓名模糊查询。
- 信息修改: 根据工号找到职工,并修改其任意一项信息。
- 信息删除: 根据工号删除指定职工的信息。
- 数据排序: 可以按照工资或年龄对职工信息进行升序或降序排序。
- 数据统计: 统计不同学历(如本科、硕士、博士)的职工人数。
- 数据保存: 所有操作后,数据自动保存到文件中,确保程序关闭后信息不丢失。
- 数据加载: 程序启动时,自动从文件中加载已有数据。
- 退出系统: 安全退出程序,并提示用户保存。
系统设计
数据结构设计
使用结构体来定义职工信息,这是C语言处理复杂数据的基础。
// 定义职工结构体
typedef struct {
int id; // 工号
char name[50]; // 姓名
char gender[10]; // 性别
int age; // 年龄
char education[20]; // 学历
float salary; // 工资
char hire_date[20]; // 入职日期
} Employee;
模块化设计
为了使代码结构清晰、易于维护和扩展,我们将系统功能分解为多个独立的函数模块。
| 模块名称 | 主要功能 |
|---|---|
| 主菜单模块 | 显示系统主菜单,接收用户输入,并调用相应功能模块。 |
| 信息录入模块 | addEmployee() - 实现职工信息的添加。 |
| 信息显示模块 | displayAllEmployees() - 实现所有职工信息的表格化显示。 |
| 信息查询模块 | searchEmployee() - 包含按工号查询和按姓名查询的子功能。 |
| 信息修改模块 | modifyEmployee() - 根据工号定位并修改职工信息。 |
| 信息删除模块 | deleteEmployee() - 根据工号删除职工信息。 |
| 数据排序模块 | sortEmployees() - 提供按工资或年龄进行升序/降序排序的选项。 |
| 数据统计模块 | countByEducation() - 统计各学历人数并显示。 |
| 文件操作模块 | saveToFile() 和 loadFromFile() - 负责数据的持久化存储和读取。 |
| 工具函数模块 | clearScreen(), pressAnyKeyToContinue() 等辅助函数。 |
文件存储设计
使用二进制文件(.dat)来存储职工数据,相比文本文件,读写效率更高,也更安全。

(图片来源网络,侵删)
- 文件名:
employees.dat - 存储方式: 将整个
Employee结构体数组一次性写入和读出文件。
核心代码实现
下面是完整的C语言代码,你可以直接复制、编译和运行。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h> // 用于 getch(),Windows平台下清屏用
#include <ctype.h> // 用于 tolower()
// --- 定义常量 ---
#define MAX_EMPLOYEES 100
#define FILENAME "employees.dat"
// --- 定义职工结构体 ---
typedef struct {
int id;
char name[50];
char gender[10];
int age;
char education[20];
float salary;
char hire_date[20];
} Employee;
// --- 全局变量 ---
Employee employees[MAX_EMPLOYEES];
int employee_count = 0;
// --- 函数声明 ---
void clearScreen();
void pressAnyKeyToContinue();
void showMenu();
void addEmployee();
void displayAllEmployees();
void searchEmployee();
void modifyEmployee();
void deleteEmployee();
void sortEmployees();
void countByEducation();
void saveToFile();
void loadFromFile();
// --- 主函数 ---
int main() {
loadFromFile(); // 程序启动时加载数据
int choice;
do {
showMenu();
printf("请输入您的选择: ");
scanf("%d", &choice);
// 清除输入缓冲区,防止输入非数字导致的问题
while (getchar() != '\n');
switch (choice) {
case 1: addEmployee(); break;
case 2: displayAllEmployees(); break;
case 3: searchEmployee(); break;
case 4: modifyEmployee(); break;
case 5: deleteEmployee(); break;
case 6: sortEmployees(); break;
case 7: countByEducation(); break;
case 0:
saveToFile();
printf("感谢使用,再见!\n");
break;
default:
printf("无效的选择,请重新输入!\n");
pressAnyKeyToContinue();
}
} while (choice != 0);
return 0;
}
// --- 函数实现 ---
// 清屏函数 (Windows)
void clearScreen() {
system("cls");
}
// 按任意键继续
void pressAnyKeyToContinue() {
printf("\n按任意键继续...");
getch();
}
// 显示主菜单
void showMenu() {
clearScreen();
printf("=============== 职工信息管理系统 ===============\n");
printf("|| ||\n");
printf("|| 1. 添加职工信息 ||\n");
printf("|| 2. 显示所有职工信息 ||\n");
printf("|| 3. 查询职工信息 ||\n");
printf("|| 4. 修改职工信息 ||\n");
printf("|| 5. 删除职工信息 ||\n");
printf("|| 6. 职工信息排序 ||\n");
printf("|| 7. 统计各学历人数 ||\n");
printf("|| 0. 退出系统 ||\n");
printf("|| ||\n");
printf("==============================================\n");
}
// 1. 添加职工信息
void addEmployee() {
clearScreen();
if (employee_count >= MAX_EMPLOYEES) {
printf("职工数量已达上限,无法添加!\n");
pressAnyKeyToContinue();
return;
}
Employee e;
printf("--- 添加新职工 ---\n");
printf("请输入工号: ");
scanf("%d", &e.id);
// 检查工号是否已存在
for (int i = 0; i < employee_count; i++) {
if (employees[i].id == e.id) {
printf("错误:该工号已存在!\n");
pressAnyKeyToContinue();
return;
}
}
printf("请输入姓名: ");
scanf("%s", e.name);
printf("请输入性别: ");
scanf("%s", e.gender);
printf("请输入年龄: ");
scanf("%d", &e.age);
printf("请输入学历: ");
scanf("%s", e.education);
printf("请输入工资: ");
scanf("%f", &e.salary);
printf("请输入入职日期(YYYY-MM-DD): ");
scanf("%s", e.hire_date);
employees[employee_count++] = e;
printf("职工信息添加成功!\n");
pressAnyKeyToContinue();
}
// 2. 显示所有职工信息
void displayAllEmployees() {
clearScreen();
if (employee_count == 0) {
printf("暂无职工信息!\n");
pressAnyKeyToContinue();
return;
}
printf("--- 所有职工信息 ---\n");
printf("---------------------------------------------------------------------------------\n");
printf("工号\t姓名\t性别\t年龄\t学历\t\t工资\t\t入职日期\n");
printf("---------------------------------------------------------------------------------\n");
for (int i = 0; i < employee_count; i++) {
printf("%d\t%s\t%s\t%d\t%-10s\t%.2f\t\t%s\n",
employees[i].id,
employees[i].name,
employees[i].gender,
employees[i].age,
employees[i].education,
employees[i].salary,
employees[i].hire_date);
}
printf("---------------------------------------------------------------------------------\n");
printf("共 %d 名职工,\n", employee_count);
pressAnyKeyToContinue();
}
// 3. 查询职工信息
void searchEmployee() {
clearScreen();
if (employee_count == 0) {
printf("暂无职工信息!\n");
pressAnyKeyToContinue();
return;
}
int choice;
printf("--- 查询职工信息 ---\n");
printf("1. 按工号查询\n");
printf("2. 按姓名查询\n");
printf("请选择查询方式: ");
scanf("%d", &choice);
if (choice == 1) {
int id;
printf("请输入要查询的工号: ");
scanf("%d", &id);
int found = 0;
for (int i = 0; i < employee_count; i++) {
if (employees[i].id == id) {
found = 1;
printf("查询结果:\n");
printf("---------------------------------------------------------------------------------\n");
printf("工号\t姓名\t性别\t年龄\t学历\t\t工资\t\t入职日期\n");
printf("---------------------------------------------------------------------------------\n");
printf("%d\t%s\t%s\t%d\t%-10s\t%.2f\t\t%s\n",
employees[i].id,
employees[i].name,
employees[i].gender,
employees[i].age,
employees[i].education,
employees[i].salary,
employees[i].hire_date);
printf("---------------------------------------------------------------------------------\n");
break;
}
}
if (!found) {
printf("未找到工号为 %d 的职工,\n", id);
}
} else if (choice == 2) {
char name[50];
printf("请输入要查询的姓名: ");
scanf("%s", name);
int found = 0;
printf("查询结果:\n");
printf("---------------------------------------------------------------------------------\n");
printf("工号\t姓名\t性别\t年龄\t学历\t\t工资\t\t入职日期\n");
printf("---------------------------------------------------------------------------------\n");
for (int i = 0; i < employee_count; i++) {
if (strstr(employees[i].name, name) != NULL) { // strstr 用于模糊匹配
found = 1;
printf("%d\t%s\t%s\t%d\t%-10s\t%.2f\t\t%s\n",
employees[i].id,
employees[i].name,
employees[i].gender,
employees[i].age,
employees[i].education,
employees[i].salary,
employees[i].hire_date);
}
}
printf("---------------------------------------------------------------------------------\n");
if (!found) {
printf("未找到姓名包含 \"%s\" 的职工,\n", name);
}
} else {
printf("无效的选择!\n");
}
pressAnyKeyToContinue();
}
// 4. 修改职工信息
void modifyEmployee() {
clearScreen();
if (employee_count == 0) {
printf("暂无职工信息!\n");
pressAnyKeyToContinue();
return;
}
int id;
printf("--- 修改职工信息 ---\n");
printf("请输入要修改的职工工号: ");
scanf("%d", &id);
int index = -1;
for (int i = 0; i < employee_count; i++) {
if (employees[i].id == id) {
index = i;
break;
}
}
if (index == -1) {
printf("未找到工号为 %d 的职工,\n", id);
} else {
printf("找到职工: %s\n", employees[index].name);
printf("请输入新的姓名 (原: %s): ", employees[index].name);
scanf("%s", employees[index].name);
printf("请输入新的性别 (原: %s): ", employees[index].gender);
scanf("%s", employees[index].gender);
printf("请输入新的年龄 (原: %d): ", employees[index].age);
scanf("%d", &employees[index].age);
printf("请输入新的学历 (原: %s): ", employees[index].education);
scanf("%s", employees[index].education);
printf("请输入新的工资 (原: %.2f): ", employees[index].salary);
scanf("%f", &employees[index].salary);
printf("请输入新的入职日期 (原: %s): ", employees[index].hire_date);
scanf("%s", employees[index].hire_date);
printf("职工信息修改成功!\n");
}
pressAnyKeyToContinue();
}
// 5. 删除职工信息
void deleteEmployee() {
clearScreen();
if (employee_count == 0) {
printf("暂无职工信息!\n");
pressAnyKeyToContinue();
return;
}
int id;
printf("--- 删除职工信息 ---\n");
printf("请输入要删除的职工工号: ");
scanf("%d", &id);
int index = -1;
for (int i = 0; i < employee_count; i++) {
if (employees[i].id == id) {
index = i;
break;
}
}
if (index == -1) {
printf("未找到工号为 %d 的职工,\n", id);
} else {
printf("确认删除职工 %s (工号: %d) 的信息吗?(y/n): ", employees[index].name, employees[index].id);
char confirm;
scanf(" %c", &confirm);
if (tolower(confirm) == 'y') {
// 将后面的元素前移,覆盖掉要删除的元素
for (int i = index; i < employee_count - 1; i++) {
employees[i] = employees[i + 1];
}
employee_count--;
printf("职工信息删除成功!\n");
} else {
printf("取消删除操作,\n");
}
}
pressAnyKeyToContinue();
}
// 6. 职工信息排序
void sortEmployees() {
clearScreen();
if (employee_count == 0) {
printf("暂无职工信息!\n");
pressAnyKeyToContinue();
return;
}
int choice, order;
printf("--- 职工信息排序 ---\n");
printf("1. 按工资排序\n");
printf("2. 按年龄排序\n");
printf("请选择排序依据: ");
scanf("%d", &choice);
printf("1. 升序\n");
printf("2. 降序\n");
printf("请选择排序方式: ");
scanf("%d", &order);
// 使用简单的冒泡排序算法
for (int i = 0; i < employee_count - 1; i++) {
for (int j = 0; j < employee_count - 1 - i; j++) {
int should_swap = 0;
if (choice == 1) { // 按工资
if (order == 1 && employees[j].salary > employees[j + 1].salary) should_swap = 1;
if (order == 2 && employees[j].salary < employees[j + 1].salary) should_swap = 1;
} else if (choice == 2) { // 按年龄
if (order == 1 && employees[j].age > employees[j + 1].age) should_swap = 1;
if (order == 2 && employees[j].age < employees[j + 1].age) should_swap = 1;
}
if (should_swap) {
Employee temp = employees[j];
employees[j] = employees[j + 1];
employees[j + 1] = temp;
}
}
}
printf("排序完成!\n");
displayAllEmployees(); // 排序后直接显示
}
// 7. 统计各学历人数
void countByEducation() {
clearScreen();
if (employee_count == 0) {
printf("暂无职工信息!\n");
pressAnyKeyToContinue();
return;
}
printf("--- 学历统计 ---\n");
char educations[MAX_EMPLOYEES][20];
int counts[MAX_EMPLOYEES] = {0};
int unique_edu_count = 0;
for (int i = 0; i < employee_count; i++) {
int found = 0;
for (int j = 0; j < unique_edu_count; j++) {
if (strcmp(employees[i].education, educations[j]) == 0) {
counts[j]++;
found = 1;
break;
}
}
if (!found) {
strcpy(educations[unique_edu_count], employees[i].education);
counts[unique_edu_count] = 1;
unique_edu_count++;
}
}
for (int i = 0; i < unique_edu_count; i++) {
printf("%s: %d 人\n", educations[i], counts[i]);
}
pressAnyKeyToContinue();
}
// 8. 保存数据到文件
void saveToFile() {
FILE *fp = fopen(FILENAME, "wb");
if (fp == NULL) {
printf("无法打开文件 %s 进行保存!\n", FILENAME);
return;
}
fwrite(&employee_count, sizeof(int), 1, fp);
fwrite(employees, sizeof(Employee), employee_count, fp);
fclose(fp);
printf("数据已成功保存到 %s\n", FILENAME);
}
// 9. 从文件加载数据
void loadFromFile() {
FILE *fp = fopen(FILENAME, "rb");
if (fp == NULL) {
printf("未找到数据文件 %s,将创建新文件,\n", FILENAME);
return;
}
fread(&employee_count, sizeof(int), 1, fp);
fread(employees, sizeof(Employee), employee_count, fp);
fclose(fp);
printf("数据已从 %s 成功加载,\n", FILENAME);
}
编译与运行说明
- 环境: 本代码在 Windows 环境下编写,使用了
conio.h库中的system("cls")和getch()函数。- 在 Windows 上 (如 Dev-C++, Visual Studio): 可以直接编译运行。
- 在 Linux 或 macOS 上:
conio.h库不可用,你需要替换这两个函数:system("cls")替换为printf("\033[2J\033[H");(ANSI转义码清屏) 或使用一个简单的循环打印多行换行符。getch()替换为getchar()。
- 编译: 将以上代码保存为
employee_management.c文件,使用 C 编译器(如gcc)进行编译:gcc employee_management.c -o employee_management
- 运行: 运行生成的可执行文件:
./employee_management
项目总结与展望
本项目成功实现了一个功能完备的C语言职工信息管理系统,通过结构体、数组、文件操作和函数模块化等核心C语言技术,完成了对职工信息的增、删、改、查、排序、统计等基本操作,并确保了数据的持久化,代码结构清晰,注释详细,具有良好的可读性和可维护性。
展望与改进方向:
- 数据结构优化: 使用链表代替数组,可以动态地管理内存,避免
MAX_EMPLOYEES的限制,使系统更灵活。 - 界面美化: 使用更高级的图形库(如 EasyX, Win32 API, 或跨平台的 GTK/Qt)来创建图形用户界面,提升用户体验。
- 功能增强:
- 增加按部门、职位等更多维度的查询和统计。
- 增加数据导出功能,如将报表导出为 Excel 或 CSV 文件。
- 增加用户登录和权限管理功能,区分管理员和普通用户。
- 算法优化: 对于大数据量,可以将排序算法从冒泡排序替换为更高效的快速排序或归并排序。
- 错误处理: 增加更健壮的输入验证和错误处理机制,防止因用户非法输入导致程序崩溃。
这个项目不仅巩固了C语言的基础知识,也锻炼了软件设计和工程实践的能力,是一个非常有价值的课程设计。

(图片来源网络,侵删)
