C语言完整课程设计代码(简单职工管理系统)
- 采用的是双向链表,排序自己写的,因为是链表排序,学校几乎没交
- 排序在增加员工处采用的是一次一插入,在插入的时候遍历整个链表,找到适当位置进行插入;
- 在排序员工的时候是对整个链表进行排序,需要涉及两条链表操作,对原链表进行结点复制(原链表不能被干扰),后对新链表进行增加结点及结点排序,每次排序都需要从头重新遍历链表
- 存储方式是姓名拼音按字典排序的文件,由于C语言没有中文转拼音的库函数,所以如果硬要的话可以自己添加,此处加入拼音做法是与老师商讨结果,毕竟考察重点是增删改查
- 代码完整,可直接运行
课设要求如下
基于C语言的简单职工管理系统,对单位的职工进行管理,包括插入、删除、查找、排序等功能。职工对象包括姓名、性别、出生年月、工作年月、学历、职务、住址、电话等信息。后台数据按姓名以字典方式职工管理文件里。
该系统最大的特点就是职工通过字典排序的方式存储进职工管理文件,并通过多种方式对职工删除、查询和修改。
功能要求:
(1)新增一名职工:将新增职工对象按姓名以字典方式职工管理文件中。
(2)删除一名职工:从职工管理文件中删除一名职工对象。
(3)查询:从职工管理文件中查询符合某些条件的职工。
(4)修改:检索某个职工对象,对其某些属性进行修改。
(5)排序:按姓名进行字典或对工资进行排序。
基本页面如下
完整代码如下
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
//职工数据结构体
struct Worker
{ //10个属性
char num[20]; //编号
char namep[20]; //姓名拼音
char name[20]; //姓名
char sex[20]; //性别
char birthday[20]; //出生年月
char workday[20]; //工作年月
char edu [20]; //学历
char job [20]; //职务
char addr[20]; //住址
char phone[20]; //电话
char salary[20] ; //工资
};
//职工链结构体
typedef struct node
{
struct Worker worker;
struct node *next;
struct node *prior;
}Node;
int getMeun(Node *worker); //获取菜单
int addWorker(Node *worker); //增加职工
int delWorker(Node *worker); //删除职工
int querWorker(Node *worker); //查询职工
int revWorker(Node *worker); //修改职工
int sorWorker(Node *worker); //排序职工
int saveFile (Node* worker); //存储到文件中
int saveNode (Node* worker); //输出排序好的链表但不更改文件
int readFile(Node *worker); //读取文件信息
int next(Node* worker); //下一步
int main()
{
Node *worker;
worker = (Node*)malloc(sizeof(Node)); //创建头结点
worker->next = worker->prior = NULL;
system("color 3f");
readFile(worker); //读取文件
getMeun (worker); //获取主菜单
return 0;
}
//主菜单
int getMeun (Node *worker)
{
int choose = 0 ;
printf("********************************************************************************************
");
printf(" 欢迎来到职工管理系统
");
printf(" 1. 新增职工
");
printf(" 2. 删除职工
");
printf(" 3. 查询职工
");
printf(" 4. 修改职工
");
printf(" 5. 排序职工
");
printf(" 0. 退出系统
");
printf(" 请输入操作数字
");
printf("********************************************************************************************
");
scanf("%d",&choose);
switch(choose)
{
case 1:
system("cls");
printf("********************************************************************************************
");
printf("欢迎进入新增职工页面
");
printf("********************************************************************************************
");
addWorker(worker);
saveFile(worker);
next(worker);
break;
case 2:
system("cls");
printf("********************************************************************************************
");
printf("欢迎进入删除职工页面
");
printf("********************************************************************************************
");
delWorker(worker);
next(worker);
break;
case 3:
system("cls");
printf("********************************************************************************************
");
printf("欢迎进入查询职工页面
");
printf("********************************************************************************************
");
querWorker(worker);
next(worker);
break;
case 4:
system("cls");
printf("********************************************************************************************
");
printf("欢迎进入修改职工页面
");
printf("********************************************************************************************
");
revWorker(worker);
saveFile(worker);
next(worker);
break;
case 5:
system("cls");
printf("********************************************************************************************
");
printf("欢迎进入排序职工页面
");
printf("********************************************************************************************
");
sorWorker(worker);
next(worker);
break;
case 0:
exit(0);
default:
system("cls");
getMeun(worker); //递归
}
}
//增加职工
int addWorker (Node *worker)
{
Node *p,*q,*pre,*k;
q = pre = worker; //头结点不存储数据
k = worker->next;
// if(q->next != NULL)
// {
// pre = q;
// q = q->next;
// q->prior = pre;
// }
printf("请依次输入:
");
printf(" 编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("eg 1901 jiangmaoqiong 江茂琼 女 199906 201906 大学 程序员 137xxxx2381 xx市xx路xx号 8000
");
p = (Node *)malloc(sizeof(Node));
scanf("%s%s%s%s%s%s%s%s%s%s%s",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
//对编号进行判断 ,循环多次判断
while(k!=NULL)
{
if(strcmp(p->worker.num ,k->worker.num) == 0)
{
printf("该编号已存在,请重新输入编号
");
scanf("%s",p->worker.num);
k = worker; //指回头结点,再次遍历判断
}
k = k->next;
}
printf("新增职工信息如下:
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
while(q!=NULL)
{
//大于前结点而且小于后结点,插入于中间
if( (strcmp(p->worker.namep,pre->worker.namep) > 0 ) && ( strcmp(p->worker.namep,q->worker.namep) < 0 ) )
{
p->next = q;
p->prior = q->prior;
q->prior = p;
p->prior->next = p;
break;
}
//插入于最后一个的后面
if( (q->next == NULL) && ( strcmp(p->worker.name,pre->worker.namep) > 0 ))
{
q->next = p;
p->prior = q;
p->next = NULL;
break;
}
pre = q;
q = q->next;
q->prior = pre;
}
}
//删除职工
int delWorker(Node *worker)
{
Node *p,*r;
char delnum[20],delname[20];
int delChoose,confirmChoose;
p = worker->next;
if( p == NULL)
{
printf("目前没有资料
");
}
else{
printf("按职工编号删除: 1
");
printf("按职工姓名删除: 2
");
printf("********************************************************************************************
");
scanf("%d",&delChoose);
if(delChoose == 1 )
{
int num=0;
printf("请输入要删除职工的编号
");
scanf("%s",&delnum);
while(p!=NULL)
{
if(strcmp(p->worker.num,delnum)==0)
{
num++;
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
printf("您是否删除%s
",p->worker.name);
printf("确认删除:1,取消删除:2
");
scanf("%d",&confirmChoose);
if(confirmChoose == 1)
{
printf("%s删除成功
",p->worker.name);
//删除该节点
if(p!=NULL)
{
r = worker;
while (r->next != p)
{
r = r->next;
}
r->next = r->next->next;
}
saveFile(worker);
}
else if(confirmChoose == 2)
{
printf("您已取消操作
");
break;
}
break;
}
else
{
if(p->next == NULL && num == 0)
{
printf("该职工不存在
");
}
}
p = p->next;
}
}//delChoose == 1
else if (delChoose == 2 )
{
printf("请输入要删除职工的姓名
");
scanf("%s",&delname);
int num=0;
while(p!=NULL)
{
if(strcmp(p->worker.name,delname)==0)
{
num++;
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
printf("您是否删除%s
",p->worker.name);
printf("确认删除:1,取消删除:2
");
scanf("%d",&confirmChoose);
if(confirmChoose == 1)
{
printf("%s删除成功
",p->worker.name);
//删除该节点
if(p!=NULL)
{
r = worker;
while (r->next != p)
{
r = r->next;
}
r->next = r->next->next;
}
saveFile(worker);
}
else if(confirmChoose == 2)
{
printf("您已取消操作
");
break;
}
break;
}
else
{
if(p->next == NULL && num == 0)
{
printf("该职工不存在
");
}
}
p = p->next;
}
}//delChoose == 2
}
};
//查询职工
int querWorker(Node *worker)
{
char querNum[20],querName[20],querJob[20],querEdu[20],querSalarySta[20],querSalaryEnd[20];
int querChoose,NumSta,NumEnd,querSalaryNum;
Node* p = worker->next;
if( p == NULL){
printf("目前没有资料
");
}
else
{
printf("通过职工编号查询: 1
");
printf("通过职工姓名查询: 2
");
printf("通过职工工资范围查询: 3
");
printf("通过职工职务查询: 4
");
printf("通过职工学历查询: 5
");
printf("请输入对应数字
");
printf("********************************************************************************************
");
scanf("%d",&querChoose);
if(querChoose == 1 )
{
int num = 0;
printf("请输入要查询的职工编号:
");
scanf("%s",&querNum);
while(p!=NULL)
{
if(strcmp(p->worker.num,querNum)==0)
{
num++;
if(num==1){
printf("********************************************************************************************
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
}
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
}
else
{
if (p->next == NULL && num == 0)
{
printf("未找到该职工
");
}
}
p = p->next;
}
}
else if (querChoose == 2 )
{
int num = 0;
printf("请输入要查询的职工姓名:
") ;
scanf("%s",&querName);
while(p!=NULL)
{
if(strcmp(p->worker.name,querName)==0)
{
num++;
if(num==1){
printf("********************************************************************************************
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
}
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
}
else
{
if (p->next == NULL && num == 0)
{
printf("未找到该职工
");
}
}
p = p->next;
}
}
else if (querChoose == 3 )
{
int num = 0 ;
printf("请输入要查询的职工工资范围:
");
printf("起始工资:");
scanf("%d",&querSalarySta);
printf("工资上限:");
scanf("%d",&querSalaryEnd);
NumSta = *(int *)querSalarySta;
NumEnd = *(int *)querSalaryEnd;
while(p!=NULL)
{
querSalaryNum = atoi(p->worker.salary); //强制类型转换的方法
if(querSalaryNum >= NumSta && querSalaryNum <= NumEnd)
{
num++;
if(num==1){
printf("********************************************************************************************
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
}
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
}
else
{
if (p->next == NULL && num == 0)
{
printf("该范围内没有职工
");
}
}
p = p->next;
}
}
else if (querChoose == 4 )
{
int num = 0 ;
printf("请输入要查询的职工职务:
") ;
scanf("%s",&querJob);
while(p!=NULL)
{
if(strcmp(p->worker.job,querJob)==0)
{
num++;
if(num==1){
printf("********************************************************************************************
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
}
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
}
else
{
if (p->next == NULL && num == 0)
{
printf("未找到该职工
");
}
}
p = p->next;
}
}
else if (querChoose == 5 )
{
int num = 0 ;
printf("请输入要查询的职工学历:
") ;
scanf("%s",&querEdu);
while(p!=NULL)
{
if(strcmp(p->worker.edu,querEdu)==0)
{
num++;
if(num==1){
printf("********************************************************************************************
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
}
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
}
else
{
if (p->next == NULL && num == 0)
{
printf("未找到该职工
");
}
}
p = p->next;
}
}
else
{
printf("输入出错,请重新选择
");
querWorker(worker);
}
}
};
//修改职工
int revWorker(Node *worker)
{
char revNum[20],revName[20];
int revChoose ;
Node *p = worker->next;
if( p == NULL){
printf("目前没有资料
");
}
else
{
printf("通过职工编号修改: 1
");
printf("通过职工姓名修改: 2
");
printf("请输入对应数字
");
printf("********************************************************************************************
");
scanf("%d",&revChoose);
if(revChoose == 1 )
{
printf("请输入要修改的职工编号
");
scanf("%s",&revNum);
int num = 0 ;
while(p!=NULL)
{
if(strcmp(p->worker.num,revNum)==0)
{
num++ ;
//显示原信息
printf("找到该职工,其信息如下
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
//修改信息
printf("
请依次输入数据进行修改:
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s ",p->worker.num);
scanf("%s%s%s%s%s%s%s%s%s%s",
p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
//修改后信息
printf("修改职工信息如下:
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("
%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
break;
}
else
{
if (p->next == NULL && num == 0)
{
printf("未找到该职工
");
}
}
p = p->next;
}
}
else if (revChoose ==2)
{
printf("请输入要修改的职工姓名
");
scanf("%s",&revName);
while(p!=NULL)
{
if(strcmp(p->worker.name,revName)==0)
{
//显示原信息
printf("找到该职工,其信息如下
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
//修改信息
printf("
请依次输入数据进行修改:
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("%s ",p->worker.num);
scanf("%s%s%s%s%s%s%s%s%s%s",
p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
//修改后信息
printf("修改职工信息如下:
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
printf("
%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
break;
}
else
{
int num = 0 ;
if (p->next == NULL && num == 0)
{
printf("未找到该职工
");
}
}
p = p->next;
}
}
}
};
//排序职工
int sorWorker(Node *worker)
{
Node* p = worker->next;
Node *sorSalary;
sorSalary = (Node*)malloc(sizeof(Node)); //创建新头结点存储新链表
sorSalary->next = sorSalary->prior = NULL;
Node *s = sorSalary->next;
Node *q;
int querSalaryNum;
int sorChoose;
if(p==NULL)
{
printf("目前没有资料
");
}
else
{
printf("按照姓名排序: 1
");
printf("按照工资排序: 2
");
printf("请输入对应数字
");
printf("********************************************************************************************
");
scanf("%d",&sorChoose);
if(sorChoose == 1)
{
printf("以下数据按姓名进行字典排序
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
while(p!=NULL)
{
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
p = p->next ;
}
}
else if (sorChoose == 2 )
{
printf("以下数据按工资进行字典排序
");
printf("编号 姓名拼音 姓名 性别 出生年月 工作年月 学历 职务 电话 住址 工资
");
//赋予 sorSalary 第一个节点值 ,与p第二个节点进行比较排序
s = (Node*)malloc(sizeof(Node));
s->worker = p->worker ;
s->prior = sorSalary;
s->next = NULL;
p = p->next;
while(p!=NULL)
//提供数据的链表
{
querSalaryNum = atoi(p->worker.salary);
q = (Node *)malloc(sizeof(Node));
//新建节点存储数据,如果只有s,会干扰原s链,而且不能干扰p链
q->worker = p->worker;
do//每一次都要遍历整个链
{
if(sorSalary->next == NULL)
{
sorSalary->next = s;
//必须关联到 sorSalary,而且只能设置一次,但是如果写在里面就会导致刷新前节点,链表中断
}
//后插,没有两个值的情况,比第一个数大 ;或遍历到最后一个且比最后一个大,注意s回到头节点重新遍历
if(querSalaryNum >= atoi(s->worker.salary) && s->next == NULL)
{
s->next = q;
q->prior = s;
q->next =NULL;
//后插法和前插法混用导致指针混乱,为了与前插法匹配 ,将指针前移
// s = s->prior;
break;
}
// 有两个以上可以进行比较,前插
else if( querSalaryNum >= atoi(s->prior->worker.salary) && querSalaryNum < atoi(s->worker.salary) )
//此处不能两个相等,而且必须有一个相等,使其在等于前者的时候进入循环,倘若后者也写相等,会进入死循环
{
q->prior = s->prior;
q->next = s;
s->prior->next = q;
s->prior = q;
break;
}
//下一个
s->prior = s;
s = s->next;
} while(s!=NULL);
s = sorSalary->next;
s->prior = sorSalary;
p = p->next;
}
saveNode (sorSalary);
}
}
}
//存储文件信息
int saveFile (Node* worker)
{
Node *p = NULL;
FILE *fp;
int saveChoose;
if(worker->next == NULL)
{
printf("没有记录
");
}
else
{
p = worker->next;
}
fp = fopen("职工资料.txt","w");
if(fp == NULL)
{
printf("文件无法打开
");
}
while(p!=NULL)
{
fprintf(fp,"%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
p = p->next;
}
fclose(fp);
}
//输出排序好的链表但不更改文件
int saveNode (Node* worker)
{
Node *p = NULL;
int saveChoose;
if(worker->next == NULL)
{
printf("没有记录
");
}
else
{
p = worker->next;
}
while(p!=NULL)
{
printf("%s %s %s %s %s %s %s %s %s %s %s
",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
p = p->next;
if(p == NULL)
{
printf("记录保存成功
");
}
}
}
//读取文件信息
int readFile(Node *worker)
{
Node *p,*r;
FILE *fp;
r = worker;
fp = fopen("职工资料.txt","rt");
p = (Node *)malloc(sizeof(Node));
fscanf(fp,"%s%s%s%s%s%s%s%s%s%s%s",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
if(fp == NULL)
{
printf("文件打开失败");
}
while(!feof(fp))
{
r->next = p;
r = p;
r->next = NULL;
p = (Node *)malloc(sizeof(Node));
fscanf(fp,"%s%s%s%s%s%s%s%s%s%s%s",
p->worker.num,p->worker.namep,p->worker.name,p->worker.sex,p->worker.birthday,p->worker.workday,p->worker.edu,p->worker.job,p->worker.addr,p->worker.phone,p->worker.salary);
}
fclose(fp);
}
//下一步操作
int next (Node* worker)
{
printf("********************************************************************************************
");
printf("返回主菜单:1; 退出系统:0
");
int nextChoose;
scanf("%d",&nextChoose);
while(true){
if(nextChoose == 1)
{
system("cls");
getMeun(worker);
}
else if (nextChoose==0)
{
exit(0);
}
else
{
printf("输入出错,请重新输入");
scanf("%d",&nextChoose);
continue;
}
}
}