C语言员工信息管理系统,支持基本的增删改查,还支持将数据保存至本地,还有一些特色功能,例如可以按照关键字查找员工信息,排序不仅仅可以对年龄排序,也可以对性别,学历等字段排序。除此之外,菜单界面用了不同颜色的字体,使菜单界面可读性更强。具体效果如下:
整个程序代码如下:(员工信息保存至WorkList.txt中,如果没有则会自动创建)
// 辅修C语言课设.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#include <Windows.h>
// 表格相关的定义
#define TABLE_LINE " +-------------------------------------------------------------------------------------------------+\n"
#define TABLE_HEAD " | \033[7mNO \033[0m | \033[7m 编号 \033[0m | \033[7m 姓名 \033[0m | \033[7m性别\033[0m | \033[7m年龄\033[0m | \033[7m 学历 \033[0m | \033[7m 联系电话 \033[0m | \033[7m 家庭住址 \033[0m |\n"
#define TABLE_CONTENT " | %03d | %-14s | %-10s | %-4s | %-4s | %-10s | %-11s | %-18s | \n"
#define WORK_NUM 999 // 可存储员工最大数量
int work_sum = 0; // 当前员工数量
// 定义员工结构体 (给变量分配存储空间)
struct work
{
char id[20]; // 员工编号
char name[20]; // 员工姓名
char sex[8]; // 员工性别
char age[5]; // 员工年龄
char educat[30]; // 员工学历
char addr[90]; // 家庭住址
char phone[20]; // 手机号码
};
work works[WORK_NUM];
// 设置控制台窗口大小
//void SetSize(unsigned uCol, unsigned uLine)
//{
// char cmd[64];
// sprintf(cmd, "mode con cols=%d lines=%d", uCol, uLine);
// system(cmd);
//}
// 光标移动
void gotoxy(int x, int y)
{
COORD pos = { x,y };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
}
//获取光标的位置x
int wherex()
{
CONSOLE_SCREEN_BUFFER_INFO pBuffer;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
return (pBuffer.dwCursorPosition.X);
}
//获取光标的位置y
int wherey()
{
CONSOLE_SCREEN_BUFFER_INFO pBuffer;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer);
return (pBuffer.dwCursorPosition.Y);
}
// 菜单
void menu()
{
/* \033[字符的显示方式;字符的颜色;字符的背景颜色m 需要显示的字符 \033[m */
/* 字符的显示方式:
0(默认值)、1(加粗)、2(灰显)、3(斜体)、4(下划线)、7(反显)、9(删除线)
字符的颜色:
30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(深蓝色)、
35(紫色)、36(浅蓝色)、37(白色)
字符的背景颜色:
40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、
45(紫色)、46(浅蓝色)、47(白色) */
printf("\n");
printf(" +-----------------------\033[7m员工管理系统\033[m-----------------------+\n");
printf(" |####\t\t\t\t\t\t\t####|\n");
printf(" |####\t\t\t\033[36m1.浏览员工信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m2.录入员工信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m3.查询员工信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m4.修改员工信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m5.删除员工信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m6.指定位置插入\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m7.排序员工信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m8.清空屏幕信息\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\033[36m0.退出员工管理\033[0m\t\t\t####|\n");
printf(" |####\t\t\t\t\t\t\t####|\n");
printf(" +----------------------------------------------------------+\n");
}
// 清空屏幕信息
void clear_info()
{
system("cls");
menu();
}
// 初始化 读取员工信息
void init_info()
{
work_sum = 0; // 当前员工数量
FILE* fp = fopen("WorkList.txt", "a+");
if (NULL == fp)
{
return;
}
// 按格式读取
while (!feof(fp))
{
fscanf(fp, "%s %s %s %s %s %s %s\n", works[work_sum].id, works[work_sum].name, works[work_sum].sex, works[work_sum].age, works[work_sum].educat, works[work_sum].phone, works[work_sum].addr);
work_sum++;
}
//printf("work_sum=%d", work_sum);
fclose(fp);
fp = NULL;
}
// 保存员工信息到硬盘
void save_info()
{
FILE* pFile;
pFile = fopen("WorkList.txt", "w+");
for (int i = 0; i < work_sum; i++)
{
fprintf(pFile, "%s %s %s %s %s %s %s\n", works[i].id, works[i].name, works[i].sex, works[i].age, works[i].educat, works[i].phone, works[i].addr);
}
fclose(pFile);
pFile = NULL;
}
// 录入员工信息
void push()
{
int count = 0; // 本次录入员工的总数
printf(" \033[32m您想要录入多少员工:>\033[0m");
scanf("%d", &count);
getchar();
for (int i = 0; i < count; i++)
{
printf("\n |\033[42m现在是第%d位\033[0m|\n", i + 1);
printf(" \033[32m员工编号:>>\033[0m");
scanf("%s", works[work_sum].id);
printf(" \033[32m员工姓名:>>\033[0m");
scanf("%s", works[work_sum].name);
printf(" \033[32m员工性别:>>\033[0m");
scanf("%s", works[work_sum].sex);
printf(" \033[32m员工年龄:>>\033[0m");
scanf("%s", &works[work_sum].age);
printf(" \033[32m员工学历:>>\033[0m");
scanf("%s", works[work_sum].educat);
printf(" \033[32m家庭住址:>>\033[0m");
scanf("%s", works[work_sum].addr);
printf(" \033[32m电话号码:>>\033[0m");
scanf("%s", works[work_sum].phone);
// 保存录入的数据到本地
FILE* pFile;
pFile = fopen("WorkList.txt", "a");
fprintf(pFile, "%s %s %s %s %s %s %s\n", works[work_sum].id, works[work_sum].name, works[work_sum].sex, works[work_sum].age, works[work_sum].educat, works[work_sum].phone, works[work_sum].addr);
fclose(pFile);
pFile = NULL;
work_sum++;
}
}
// 浏览员工信息
void list()
{
printf("\n");
printf(TABLE_LINE);
printf(TABLE_HEAD);
printf(TABLE_LINE);
for (int i = 0; i < work_sum; i++)
{
printf(TABLE_CONTENT, i + 1, works[i].id, works[i].name, works[i].sex, works[i].age, works[i].educat, works[i].phone, works[i].addr);
printf(TABLE_LINE);
}
printf(" |\033[31;43m如果显示格式错乱,请将窗口适当放大\033[0m|\n");
}
// 查询员工信息
void find()
{
char str[99] = "";
printf(" \033[32m请输入关键字查找:>\033[0m");
scanf("%s", str);
getchar();
printf(" \033[32m正在搜索,请稍后......\033[0m");
printf("\n");
printf(TABLE_LINE);
printf(TABLE_HEAD);
printf(TABLE_LINE);
//printf("%s", str);
for (int i = 0; i < work_sum; i++)
{
if (!strcmp(str, works[i].name) ||
!strcmp(str, works[i].sex) ||
!strcmp(str,works[i].id) ||
!strcmp(str,works[i].age) ||
!strcmp(str,works[i].educat)||
!strcmp(str,works[i].phone) ||
!strcmp(str,works[i].addr))
{
printf(TABLE_CONTENT, i + 1, works[i].id, works[i].name, works[i].sex, works[i].age, works[i].educat, works[i].phone, works[i].addr);
printf(TABLE_LINE);
}
}
printf(" |\033[31;43m如果显示格式错乱,请将窗口适当放大\033[0m|\n");
printf(" \033[32m搜索完毕!\033[0m\n");
}
// update()函数使用
void update_subitem(char str[], int num)
{
int x = 0; // 光标位置x
int y = 0; // 光标位置y
int key = 13; // 按键,这里为确认键
key = _getch();
x = wherex();
y = wherey();
if (key != 13)
{
int length = strlen(str);
gotoxy(x - length, y);
for (int i = 0; i < length; i++)
{
printf(" ");
}
gotoxy(x - length, y);
scanf("%s", str);
}
else
{
printf("\n");
}
}
// 修改员工信息
void update()
{
// 先用员工编号找到相应序号,然后修改
char id[20]; // 要删除的员工编号
int num = -1; // 要删除的序号
int x = 0; // 光标位置x
int y = 0; // 光标位置y
int key = 13; // 按键,这里为确认键
printf(" \033[32m请输入员工编号修改:>\033[0m");
scanf("%s", &id);
for (int i = 0; i < work_sum; i++)
{
if (strcmp(works[i].id, id) == 0)
{
num = i;
break;
}
}
if (num < 0 || num > work_sum)
{
printf(" \033[32m抱歉,没有这个编号\033[0m\n");
return;
}
// 开始修改
printf(" \033[32m该员工信息如下:\n\033[0m");
printf(TABLE_LINE);
printf(TABLE_HEAD);
printf(TABLE_LINE);
printf(TABLE_CONTENT, num + 1, works[num].id, works[num].name, works[num].sex, works[num].age, works[num].educat, works[num].phone, works[num].addr);
printf(TABLE_LINE);
printf(" |\033[31;43m如果显示格式错乱,请将窗口适当放大\033[0m|\n");
// 开始修改员工编号
work* index = works;
for (int i = 0; i < num; i++)
{
index++;
}
printf("\n");
printf(" \033[32m员工编号:>>\033[0m%s", works[num].id);
update_subitem(index->id, num);
printf(" \033[32m员工姓名:>>\033[0m%s", works[num].name);
update_subitem(index->name, num);
printf(" \033[32m员工性别:>>\033[0m%s", works[num].sex);
update_subitem(index->sex, num);
printf(" \033[32m员工年龄:>>\033[0m%s", works[num].age);
update_subitem(index->age, num);
printf(" \033[32m员工学历:>>\033[0m%s", works[num].educat);
update_subitem(index->educat, num);
printf(" \033[32m家庭住址:>>\033[0m%s", works[num].addr);
update_subitem(index->addr, num);
printf(" \033[32m电话号码:>>\033[0m%s", works[num].phone);
update_subitem(index->phone, num);
save_info();
}
// 指定位置插入员工信息(前插)
void insert()
{
// 先用员工编号找到相应序号,然后修改
char id[20]; // 要删除的员工编号
int num = -1; // 要删除的序号
printf(" \033[32m请输入员工编号插入该员工前面:>\033[0m");
scanf("%s", &id);
for (int i = 0; i < work_sum; i++)
{
if (strcmp(works[i].id, id) == 0)
{
num = i;
break;
}
}
if (num < 0 || num > work_sum)
{
printf(" \033[32m抱歉,没有这个编号\033[0m\n");
return;
}
// 开始插入
for (int i = work_sum; i > num; i--)
{
works[i] = works[i - 1];
}
printf(" \033[32m员工编号:>>\033[0m");
scanf("%s", works[num].id);
printf(" \033[32m员工姓名:>>\033[0m");
scanf("%s", works[num].name);
printf(" \033[32m员工性别:>>\033[0m");
scanf("%s", works[num].sex);
printf(" \033[32m员工年龄:>>\033[0m");
scanf("%s", &works[num].age);
printf(" \033[32m员工学历:>>\033[0m");
scanf("%s", works[num].educat);
printf(" \033[32m家庭住址:>>\033[0m");
scanf("%s", works[num].addr);
printf(" \033[32m电话号码:>>\033[0m");
scanf("%s", works[num].phone);
work_sum++;
printf(" \033[32m插入完毕!\033[0m\n");
save_info();
}
// 删除员工信息
void remove()
{
// 先用员工编号找到相应序号,然后删除
char id[20]; // 要删除的员工编号
int num = -1; // 要删除的序号
char choose[6];
printf(" \033[32m请输入员工编号删除:>\033[0m");
scanf("%s", &id);
for (int i = 0; i < work_sum; i++)
{
if (strcmp(works[i].id, id) == 0)
{
num = i;
break;
}
}
if (num < 0 || num > work_sum)
{
printf(" \033[32m抱歉,没有这个编号\033[0m\n");
return;
}
// 开始删除
printf(" \033[32m该员工信息如下:\n\033[0m");
printf(TABLE_LINE);
printf(TABLE_HEAD);
printf(TABLE_LINE);
printf(TABLE_CONTENT, num + 1, works[num].id, works[num].name, works[num].sex, works[num].age, works[num].educat, works[num].phone, works[num].addr);
printf(TABLE_LINE);
printf(" |\033[31;43m如果显示格式错乱,请将窗口适当放大\033[0m|\n");
printf("\n \033[32m再次确定是否删除(y/n)>>\033[0m");
scanf("%s", &choose);
if (strcmp(choose, "y") == 0 ||
strcmp(choose, "Y") == 0 ||
strcmp(choose, "yes") == 0 ||
strcmp(choose, "YES") == 0)
{
for (int i = num; i < work_sum - 1; i++)
{
works[i] = works[i + 1];
}
work_sum--;
printf(" \033[32m删除完毕!\033[0m\n");
save_info(); // 保存
}
else
{
printf(" \033[32m已取消删除\n\033[0m");
}
}
// 对员工信息排序 (可对数值类型和字符串类型排序)
void sort()
{
// 一定要记得初始化,不然直接拿来运算会出错
int count[WORK_NUM] = { 0 };
work temp_work;
int temp_count;
char choose[6];
printf(" \033[32m请选择需要排序的字段:a.编号 b.性别 c.年龄 d.学历\n >>\033[0m");
scanf("%s", choose);
// 字符串排序
for (int i = 0; i < work_sum; i++)
{
if (strcmp(choose, "a") == 0 || strcmp(choose, "A") == 0) // 按编号排序
{
int length = strlen(works[i].id);
for (int j = 0; j < length; j++)
{
count[i] += works[i].id[j];
}
//printf("id=%s count=%d | ", works[i].id, count[i]);
}
else if (strcmp(choose, "b") == 0 || strcmp(choose, "B") == 0) // 按性别排序
{
int length = strlen(works[i].sex);
for (int j = 0; j < length; j++)
{
count[i] += works[i].sex[j];
}
//printf("sex=%s count=%d | ", works[i].sex, count[i]);
}
else if (strcmp(choose, "c") == 0 || strcmp(choose, "C") == 0) // 按年龄排序
{
// 数字排序
int value = atoi(works[i].age); // 字符串转整型
count[i] = value;
//printf("age=%s count=%d | ", works[i].age, count[i]);
}
else if (strcmp(choose, "d") == 0 || strcmp(choose, "D") == 0) // 按学历排序
{
int length = strlen(works[i].educat);
for (int j = 0; j < length; j++)
{
count[i] += works[i].educat[j];
}
//printf("educat=%s count=%d | ", works[i].educat, count[i]);
}
else
{
printf(" \033[31m输入错误!\n\033[0m");
return;
}
}
// 优化后的冒泡排序
bool flag;
for (int i = 0; i < work_sum; i++)
{
flag = true;
for (int j = 0; j < work_sum - 1 - i; j++)
{
if (count[j] > count[j + 1])
{
flag = false;
temp_count = count[j + 1];
count[j + 1] = count[j];
count[j] = temp_count;
temp_work = works[j + 1];
works[j + 1] = works[j];
works[j] = temp_work;
}
}
if (flag) { break; }
}
// 列出操作后的表
list();
printf("\n \033[32m排序完毕,是否保存(y/n)>>\033[0m");
scanf("%s", &choose);
if (strcmp(choose, "y") == 0 ||
strcmp(choose, "Y") == 0 ||
strcmp(choose, "yes") == 0 ||
strcmp(choose, "YES") == 0)
{
save_info();
printf(" \033[32m保存成功!\n\033[0m");
}
else
{
init_info(); // 还原works[WORK_NUM]
printf(" \033[32m已取消保存\n\033[0m");
}
}
int main()
{
int choose;
printf("加载中,请稍后......");
//SetSize(150, 40);
init_info();
clear_info();
while (true)
{
choose = 0;
printf("\n \033[32m尊敬的领导,请选择您的操作:>\033[0m");
scanf("%d", &choose);
getchar();
switch (choose)
{
case 1:list(); break;
case 2:push(); break; // 现在没有对输入的编号检查是否重复
case 3:find(); break;
case 4:update(); break;
case 5:remove(); break;
case 6:insert(); break;
case 7:sort(); break;
case 8:clear_info(); break;
case 0:exit(0); break;
default:printf(" \033[32m抱歉,没有这个选项\033[0m\n");
break;
}
}
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
整个项目下载链接(2种方式):
1.csdn资源下载
2.蓝奏云下载