概述
本系统有小部分代码借鉴了以下这位朋友的代码,并加以改进,大部分代码,都是自己编写的.
作者:F__Rong
来源:CSDN
原文:https://blog.csdn.net/f__rong/article/details/75765571
注意:因为我模块分的比较多,代码量很大,不太好组织和粘贴,我只把部分代码粘贴进来,供给各位参考.
需要的朋友可以自己去下载:https://download.csdn.net/download/pjfxiaopan2/10745603
如果没有没有积分的朋友,可以留言你的QQ邮箱,我有空的时候给你发
简介
这个是我自己用C语言编写的员工信息管理系统,算是我这一点时间来对所学习C语言的一个总结的作品.代码量还是蛮大的.功能比较丰富,包含了三个端,员工端,部门经理端,超级管理员端. 员工端可以申请请假/加薪/转正(如果是试用期)/查看自己本月应得工资等操作.部门管理员可以对员工的申请进行审核等操作.管理员可以设置公司组织机构等操作.
本系统对于正在学习以及刚学习完C语言,希望巩固一下语法知识的朋友,具有比较高的借鉴意义.比如数组/函数指针的使用/对文件的写入和读取/结构体的设计/枚举等语法的善用/光标的控制/界面的美化(本系统并没有做具体的美化,但是提供了几个美化的函数,比如设置颜色的函数Color(),以及控制光标的函数controlcursor()等函数,你可以自己去美化);
注意,本系统是使用VS2015编写的.所以如果用VC来运行的话,需要自己修改部分语法.
管理员密码在admin.txt文件中
员工和部门经理密码在初始都是123456
图片:
// main()主文件以及algorithm.h算法模块代码
#include "Login.h"
#include "file.h"
#include "Menu.h"
int main()
{
//加载数据
Load();
//登入模块
int nRet = Login();
switch (nRet)
{
case 0:
EXIT();
case 1:
g_nLevel = e_admin; //登录成功,则权限为管理员;
while (MainMenu_1())//管理员主界面
;
break;
case 2: //部门经理主界面
g_nLevel = e_manager;
while (MainMenu_3())//部门经理主界面
;
break;
case 3:
g_nLevel = e_worker;
while (MainMenu_2())//员工主界面
;
}
return 0;
}
// algorithm.h算法模块
#include "algorithm.h"
//打印部门职位
static void PrintPost(char *pName);
static bool SortbyNum(S_WORKER*, S_WORKER*);//工号
static bool SortbyName(S_WORKER*, S_WORKER*);//姓名
static bool SortbySala(S_WORKER*, S_WORKER*);//基本工资
static bool SortbyPost(S_WORKER*, S_WORKER*);//部门
static void ModifyPsw_1();//员工修改密码
static void ModifyPsw_2();//部门经理修改密码
static void ModifyPsw_3();//超级管理员修改密码
void Delete_dpt();
void Delete_post();
void Delete_manager();
void Delete_Request();//删除员工节点
void Delete_worker();//释放员工链表堆内存
//void setColor(unsigned short backColor = 0, unsigned short textColor = 7);
void setColor(char c1 = '0', char c2 = '7');
void AddSnode_Worker(S_WORKER * pworker)
{
PWORKER pnode = (PWORKER)malloc(sizeof(SWORKER));
pnode->s_data = *pworker;
pnode->s_pNext = g_worker_head;
g_worker_head = pnode;
}
void AddSnode_Manager(S_DADMIN *pdata)
{
PDADMIN pnode = (PDADMIN)malloc(sizeof(S_NODE_DEPARTMENT_ADMIN));
pnode->data = *pdata;
pnode->pnext = g_dptManger_head;
g_dptManger_head = pnode;
}
unsigned short GetMonth()//获取当前月份
{
time_t timer;
time(&timer);
tm *ptime = localtime(&timer);
asctime(ptime);
//printf("%d", time->tm_mon+1);
return ptime->tm_mon;
}
time_t GetNowTime()//获取当前时间
{
time_t timer;
time(&timer);
return timer;
}
int Confirm_Number()
{
int n = 0;
do
{
printf("请选择:");
int nRet = scanf("%d", &n);
if (!nRet)
{
printf("只能输入数字哦!n");
rewind(stdin);
continue;
}
else
break;
} while (true);
return n;
}
void Print_Worker(S_WORKER *pworker)
{
if (g_worker_head == NULL)
{
printf("无信息可打印");
return;
}
system("cls");
printf("工号 姓名 性别 职务 所属部门 状态1 实际工资 加班 请假 处分 状态2 员工请求n");//状态1为是否正式工,2为是否请假/休假/离职
PWORKER pNode = g_worker_head;
printf("_________________________________________________________________________________________________________n");
if (pworker)
{
if (g_nLevel == e_manager)
{
if (strcmp(pworker->ss_Dpt, gp_manager->ss_Department) == 0)
printf("%-8s%-10s%-8s%-12s%-12s%-12s%-9.0f%-6d%-6d%-6d%-12s%-15sn", pworker->ss_Number, pworker->ss_Name,
pworker->b_sex ? "男" : "女", pworker->ss_Post, pworker->ss_Dpt, pworker->b_test ? "正式工" : "试用期", pworker->s_Sala.f_real,
pworker->cOverDays, pworker->cLeaveDays, pworker->cPunish, pState[pworker->State], pRequest[pworker->e_request]);
else
printf("您无权查看该员工信息!");
}
if(g_nLevel==e_admin || g_nLevel==e_worker)
printf("%-8s%-10s%-8s%-12s%-12s%-12s%-9.0f%-6d%-6d%-6d%-12s%-13sn", pworker->ss_Number, pworker->ss_Name,
pworker->b_sex ? "男" : "女", pworker->ss_Post, pworker->ss_Dpt, pworker->b_test ? "正式工" : "试用期", pworker->s_Sala.f_real,
pworker->cOverDays, pworker->cLeaveDays, pworker->cPunish, pState[pworker->State], pRequest[pworker->e_request]);
return;
}
while (pNode)
{
if (g_nLevel == e_manager && strcmp(pNode->s_data.ss_Dpt, gp_manager->ss_Department) == 0)
{//如果是部门主管,则只能查看自己所属部门的员工.
printf("%-8s%-10s%-8s%-12s%-12s%-12s%-9.0f%-6d%-6d%-6d%-12s%-13sn", pNode->s_data.ss_Number, pNode->s_data.ss_Name,
pNode->s_data.b_sex ? "男" : "女", pNode->s_data.ss_Post, pNode->s_data.ss_Dpt, pNode->s_data.b_test ? "正式工" : "试用期", pNode->s_data.s_Sala.f_real,
pNode->s_data.cOverDays, pNode->s_data.cLeaveDays, pNode->s_data.cPunish, pState[pNode->s_data.State], pRequest[pNode->s_data.e_request]);
}
if(g_nLevel==e_admin)
{
printf("%-8s%-10s%-8s%-12s%-12s%-12s%-9.0f%-6d%-6d%-6d%-12s%-13sn", pNode->s_data.ss_Number, pNode->s_data.ss_Name,
pNode->s_data.b_sex ? "男" : "女", pNode->s_data.ss_Post, pNode->s_data.ss_Dpt, pNode->s_data.b_test ? "正式工" : "试用期", pNode->s_data.s_Sala.f_real,
pNode->s_data.cOverDays, pNode->s_data.cLeaveDays, pNode->s_data.cPunish, pState[pNode->s_data.State], pRequest[pNode->s_data.e_request]);
}
pNode = pNode->s_pNext;
}
}
//输入参数为只打印指定的职位信息.否则为全部打印
void Print_post(char *pName)
{
if (!g_post_head)
{
printf("当前无职位信息!");
system("pause");
return;
}
puts("职位名称 基本工资 试用期工资 所属部门");
PPOST pnode = g_post_head;
if (!pName)
{
while (pnode)
{
printf("%-15s%-15.0f%-10.0f%12sn", pnode->data.ss_postName, pnode->data.f_baseSala,
pnode->data.f_TestSala, pnode->data.ss_dptName);
pnode = pnode->pnext;
}
}
else
{
bool flag = false;
while (pnode)
{
if (strcmp(pName, pnode->data.ss_dptName) == 0)
{
flag = true;
printf("%-10s%-10f%-10f%10sn", pnode->data.ss_postName, pnode->data.f_baseSala,
pnode->data.f_TestSala, pnode->data.ss_dptName);
}
pnode = pnode->pnext;
}
if (!flag)
{
printf("未找到该职位信息!");
}
}
}
/
以下代码为组织的增删改查/
/
void PrintDpt(S_DPT * pdata)
{
// system("cls");
if (pdata)
{
printf("%-10s%-15s%-10s%-10sn", pdata->ss_dptNum, pdata->ss_dptName, pdata->ss_dpt_manager,
pdata->ss_dpt_manager_num);
printf("----------------------------------------------------------n");
return;
}
if (!g_dpt_head)
{
puts("当前无部门信息,请添加!");
return;
}
PDPT pnode = g_dpt_head;
printf("部门编号 部门名称 部门主管 主管编号 其他n");
while (pnode)
{
printf("%-10s%-15s%-10s%-10sn",pnode->data.ss_dptNum,pnode->data.ss_dptName, pnode->data.ss_dpt_manager,
pnode->data.ss_dpt_manager_num);
//printf("n");
//printf("t+++此部门包含职位:");
//PrintPost(pnode->data.ss_dptName);//根据部门编号,打印职位
//printf("n");
printf("----------------------------------------------------------n");
//printf("nn");
pnode = pnode->pnext;
}
}
bool CheckDpt(char* pchar, int nindex, S_DPT** ppdata) //找到返回true,否则返回false
{
if (!g_dpt_head)
return false;
PDPT pnode = g_dpt_head;
while (pnode)
{
if (nindex == 1)
{
if (strcmp(pchar, pnode->data.ss_dptNum) == 0)
{
if (ppdata) //如果ppdata不是NULL,就返回被找到的数据地址
*ppdata = &pnode->data;
return true;
}
}
if(nindex == 2)
{
if (strcmp(pchar, pnode->data.ss_dptName) == 0)
{
if (ppdata) //如果ppdata不是NULL,就返回被找到的数据地址
*ppdata = &pnode->data;
return true;
}
}
if (nindex == 3)
{
if (strcmp(pchar, pnode->data.ss_dpt_manager_num) == 0)
{
if (ppdata) //如果ppdata不是NULL,就返回被找到的数据地址
*ppdata = &pnode->data;
return true;
}
}
pnode = pnode->pnext;
}
return false;
}
bool CheckPostName(char * pName, S_POST ** ppdata)
{
if (g_post_head == NULL)
return false;
PPOST pnode = g_post_head;
while (pnode)
{
if(strcmp(pnode->data.ss_postName, pName) == 0)
{
if (ppdata)
*ppdata = &pnode->data;
return true;
}
pnode = pnode->pnext;
}
return false;
}
bool CheckWorker(char *pNum, S_WORKER **ppworker)
{
if (!g_worker_head)
return false;
PWORKER pnode = g_worker_head;
while (pnode)
{
if (strcmp(pNum, pnode->s_data.ss_Number) == 0)
{
if (ppworker)
*ppworker = &pnode->s_data;
return true;
}
pnode = pnode->s_pNext;
}
return false;
}
bool CheckDManager(char *pNum, S_DADMIN **ppManager)
{
if (!g_dptManger_head)
return false;
PDADMIN pnode = g_dptManger_head;
while (pnode)
{
if (strcmp(pNum, pnode->data.ss_Num) == 0)
{
if (ppManager)
*ppManager = &pnode->data;
return true;
}
pnode = pnode->pnext;
}
return false;
}
int Delete_Manager()
{
char sNum[15];
while (1)
{
system("cls");
printf("请输入要删除的工号:");
scanf_s("%s", sNum, sizeof(sNum));
if (strlen(sNum) == 0)
{
printf("长度不能长于14个字符n");
system("pause");
continue;
}
S_DADMIN *pManager=NULL;
if (!CheckDManager(sNum, &pManager))
{
printf("未找到该主管工号,请重新输入.n");
system("pause");
continue;
}
Print_DptManager(pManager);
printf("确定要删除此主管信息吗?(y/n):");
if (!goOn())
{
puts("您取消了当前的删除操作");
Sleep(2000);
return 0;
}
PDADMIN pnode = g_dptManger_head,p1=NULL;
if (strcmp(pnode->data.ss_Num, sNum) == 0)
{
g_dptManger_head = g_dptManger_head->pnext;
free(pnode);
break;
}
p1 = pnode;
while (pnode)
{
if (strcmp(pnode->data.ss_Num, sNum) == 0)
{
p1->pnext = pnode->pnext;
free(pnode);
break;
}
p1 = pnode;
pnode = pnode->pnext;
}
break;
}
S_DPT *pDpt = NULL;
if (CheckDpt(sNum, 1, &pDpt)) //同步更新到dpt.txt;
{
strcpy(pDpt->ss_dpt_manager, "暂无");
strcpy(pDpt->ss_dpt_manager_num, "暂无");
}
puts("删除成功!");
return 0;
}
void AddSnode_Dpt(S_DPT *data)//头插法
{
PDPT pnode = (PDPT)malloc(sizeof(S_NODE_DPT));
pnode->data = *data;
pnode->pnext = g_dpt_head;
g_dpt_head = pnode;
}
void ModifySnode_Dpt(S_DPT * pdata)
{
system("cls");
printf("您当前要修改的记录为信息为:n");
PrintDpt(pdata);
printf("确认要修改吗?(y/n):");
if (!goOn())
{
printf("您取消了本次修改!");
Sleep(1000);
return;
}
char oldName[15];
strcpy(oldName, pdata->ss_dptName);//拷贝原名称
system("cls");
puts("新编号:");
puts("新部门名称:");
COORD coord = {7,0};
while (1)
{
gotoxy(7, 0);
char snum[15];
scanf_s("%s", snum, sizeof(snum));
if (strlen(snum) == 0)
{
controlcursor(coord, "编号不能长于14个字符!");
continue;
}
strcpy(pdata->ss_dptNum, snum);
break;
}
coord = { 11,1 };
while (1)
{
gotoxy(11, 1);
char sName[15];
scanf_s("%s", sName, sizeof(sName));
if (strlen(sName) == 0)
{
controlcursor(coord, "名称不能长于7个字符");
continue;
}
strcpy(pdata->ss_dptName, sName);
break;
}
Uplist_Post(oldName, pdata->ss_dptName);//联动更新g_post_head
Uplist_worker(oldName, pdata->ss_dptName);//联动更新g_worker_head
Uplist_manager(oldName, pdata->ss_dptName);//联动更新g_worker_head
}
int DptManage_Menu()
{
system("cls");
puts("1.查看主管列表");
puts("2.添加部门主管");
puts("3.删除部门主管");
puts("4.返回上一级");
puts("0.退出程序");
printf("请选择:");
int n = Confirm_Number();
switch (n)
{
case 1:
Print_DptManager();
system("pause");
break;
case 2:
while (Add_DptManager())
;
Save_Manager();
Save_dpt();
break;
case 3:
while (Delete_Manager())
;
Save_Manager();
Save_dpt();
break;
case 4:
return 0;
break;
case 0:
EXIT();
}
return n;
}
void Print_DptManager(S_DADMIN * pManager)
{
if (g_dptManger_head == NULL)
{
printf("当前主管列表为空,请现在添加部门主管");
Sleep(2000);
return;
}
//system("cls");
printf("工号 姓名 性别 管理部门 实际工资n");//状态1为是否正式工,2为是否请假/休假/离职
printf("___________________________________________________________________________n");
if (pManager)
{
printf("%-8s%-10s%-8s%-15s%-9.0fn", pManager->ss_Num, pManager->ss_Name, pManager->b_sex ? "男" : "女",
pManager->ss_Department, pManager->s_Sala.f_base);
return;
}
PDADMIN pnode = g_dptManger_head;
while (pnode)
{
printf("%-8s%-10s%-8s%-15s%-9.0fn",pnode->data.ss_Num,pnode->data.ss_Name,pnode->data.b_sex?"男":"女",
pnode->data.ss_Department,pnode->data.s_Sala.f_base);
pnode = pnode->pnext;
}
}
int Add_DptManager()
{
system("cls");
puts("工号:");
puts("姓名:");
puts("性别: (0为女,1为男)");
puts("管理的部门:");
puts("工资:");
S_DADMIN Manager;
COORD coord = { 5,0 };
while (1) //工号
{
gotoxy(5, 0);
scanf_s("%s", Manager.ss_Num, sizeof(Manager.ss_Num));
if (strlen(Manager.ss_Num) == 0)
{
controlcursor(coord, "工号不能长于14个字符.");
continue;
}
if (CheckDManager(Manager.ss_Num))//检查工号是否有重复.
{
controlcursor(coord, "该工号已存在!");
continue;
}
break;
}
coord = { 5,1 };
while (1) //姓名
{
gotoxy(5, 1);
scanf_s("%s", Manager.ss_Name, sizeof(Manager.ss_Name));
if (strlen(Manager.ss_Name) == 0)
{
controlcursor(coord, "姓名不能长于7个汉字.");
continue;
}
break;
}
coord = { 5,2 };
while (1) //性别
{
gotoxy(5, 2);
rewind(stdin);
char c;
scanf("%c", &c);
if (c != '0' && c != '1')
{
controlcursor(coord, "只能输入0或者1");
continue;
}
c == '0' ? Manager.b_sex = 0 : Manager.b_sex = 1;
break;
}
coord = { 11,3 };
S_DPT *pdpt;
while (1) //所管理的部门
{
gotoxy(11, 3);
scanf_s("%s", Manager.ss_Department, sizeof(Manager.ss_Department));
if (strlen(Manager.ss_Department) == 0)
{
controlcursor(coord, "职务名称不能长于7个汉字.");
continue;
}
if (!CheckDpt(Manager.ss_Department,2,&pdpt))
{
controlcursor(coord, "当前无此部门名称!");
continue;
}
break;
}
coord = { 5,4 };
while (1)
{
gotoxy(5, 4);
rewind(stdin);
int n = scanf("%f", &Manager.s_Sala.f_base);
if (!n)
{
controlcursor(coord, "只能输入数字!");
continue;
}
Manager.s_Sala = { GetMonth(), Manager.s_Sala.f_base,0,0, Manager.s_Sala.f_base ,"" };
break;
}
strcpy(pdpt->ss_dpt_manager, Manager.ss_Name);//同步更新到dpt.txt文件
strcpy(pdpt->ss_dpt_manager_num, Manager.ss_Num);//同步更新到dpt.txt文件
pdpt->ss_Free[0] = '