C语言链表员工信息管理系统实验报告材料册.docx
《C语言链表员工信息管理系统实验报告材料册.docx》由会员分享,可在线阅读,更多相关《C语言链表员工信息管理系统实验报告材料册.docx(27页珍藏版)》请在冰豆网上搜索。
C语言链表员工信息管理系统实验报告材料册
电子科技大学成都学院
实验报告册
课程名称:
C语言课程设计
姓名:
蒋明轩
学号:
1530720218
院系:
微电子技术系
专业:
嵌入式系统工程
教师:
孙轲
2016年5月30日
第1章设计目的设计整体框架
1.1设计任务
现对员工信息的管理,包括姓名,工号,性别,测评成绩,以及等级,可以实现对于员工信息的输入,插入,删除,排序,修改,统计,查询,保存。
1.2设计要求
员工信息的输入,插入,删除,排序,修改,统计,查询,保存等
1.3设计意义
此程序用于新建及管理员工信息,其包括员工工号,姓名,性别,以及员工的考核成绩,在程序中根据提示信息输入相关内容,输入完成后,可对其输入的内容进行修改,删除,追加,统计等操作,操作完成后保存文件,文件在下一次启动程序时将进行自动读取信息内容。
第2章设计方案
2.1软件工作
主函数中开始读取保存的TXT文件,若不存在则建立该文件,根据的选项,循环调用各个功能模块,直到选择退出时,将标识符改变,退出循环,退出该程序。
2.2模块流程图
第3章实现功能
3.1实现功能描述
主函数:
检测是否有对应的文件,若存在则打开该文件,否则则建立该文件,设置标识符循环功能模块,根据输入选项选择需要使用的功能;
增加员工信息:
根据工号判断是否需要动态分配存储空间,而后输入员工信息;
查询员工信息:
在链表节点中查找对应信息的节点,并打印节点信息;
删除员工信息:
在链表中查找对应信息节点,查找到后将节点指向更改后,释放对应节点信息;
修改员工信息:
查找对应信息,然后重新输入该节点信息;
插入员工信息:
打印员工信息,并选择需要插入的节点,链表中指向该节点后的指针,分配一个新的空间,输入信息,并更改指针指向;
统计员工信息:
统计员工中各个等级的员工个数,并打印;
排序:
根据员工分数,降序排列员工信息,并打印;
保存:
利用指针函数保存链表中的信息;
3.2模块功能描述
增加员工信息:
根据工号判断是否需要动态分配存储空间,而后输入员工信息;
查询员工信息:
在链表节点中查找对应信息的节点,并打印节点信息;
删除员工信息:
在链表中查找对应信息节点,查找到后将节点指向更改后,释放对应节点信息;
修改员工信息:
查找对应信息,然后重新输入该节点信息;
插入员工信息:
打印员工信息,并选择需要插入的节点,链表中指向该节点后的指针,分配一个新的空间,输入信息,并更改指针指向;
统计员工信息:
统计员工中各个等级的员工个数,并打印;
排序:
根据员工分数,降序排列员工信息,并打印;
保存:
利用指针函数保存链表中的信息;
第4章调试与实现
4.1调试中遇到的重点和难点
在使用链表时对于链表节点的指向不清,操作地址混淆
4.2解决办法
利用画图的方法,明确对指针指向的问题
4.3实现展示
显示员工信息
主程序显示
查询
删除
统计
第5章总结
通过此次实验,让我认识到了自身能力的不足,也发现了平时一些不易发现的小毛病,让我意识到了程序中,任何一个小的细节,将会导致的大问题,比如在此次程序的编写中,一个微不足道的取地址符将会导致内存的崩溃和输出内容的错误,使我养成了检查代码的习惯;此次程序中,我使用的是链表,在学习数据结构理论知识时,觉得链表使用应该是简单,方便,快捷的,但通过此次实践证明,理论与实际的巨大差距,不但对指针的认识更加具体,也让我磨炼了意志力,学会了责任与担当,挑战了个人能力,认识自身缺点。
第6章代码清单
#include"windows.h"
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
intsaveflag=0;//是否需要存盘的标志变量
structworker
{
charname[10];
charnum[10];//工号
charsex[5];
intsorce[5];
chardj[10];
};
typedefstructnode
{
structworkerdata;
structnode*next;
}Node,*Link;
//Linkl(注意是:
字母l不是数字1)
voidadd(Linkl);
voiddisp(Linkl);//查看员工所有信息
voiddel(Linkl);//删除功能
Node*Locate(Linkl,charfindmess[],charnameornum[]);
voidserch(Linkl);//查询功能
voidTongji(Linkl);//统计
voidSort(Linkl);//排序
voidChange(Linkl);//修改功能
voidsave(Linkl);//将链表中的数据写入文件
voidprinte(Node*p);//本函数用于打印链表中某个节点的数据内容
//以下4个函数用于输出中文标题
voidprintstart();
voidWrong();
voidNofind();
voidprintc();
voidShow_Window()
{
system("colorF4");
printf("\t*****************************************************************\n");
printf("\t**\n");
printf("\t*[1]增加员工信息[2]删除员工信息*\n");
printf("\t*[3]查询员工信息[4]修改员工信息*\n");
printf("\t*[5]插入员工记录[6]统计员工记录*\n");
printf("\t*[7]排序[8]保存员工信息*\n");
printf("\t*[9]显示数据[0]退出系统*\n");
printf("\t**\n");
printf("\t*****************************************************************\n");
}//voidShow_Window菜单结束
voidDisp(Linkl)//显示链表中存储的员工记录,内容为worker结构中定义的内容
{
intcount=0;
Node*p;
p=l->next;//l存储的是单链表中头结点的指针,该头结点没有存储员工信息,指针域指向的后继结点才有员工信息
if(!
p)/*p==NULL,NUll在stdlib中定义为0*/
{
printf("\n\t提示:
没有员工记录可以显示!
\n");
return;
}
printf("\t\t\t\t显示结果\n");
printstart();//打印横线
printc();//打印标题
printf("\n");
while(p)//逐条输出链表中存储的员工信息
{
printe(p);
p=p->next;
}
printstart();
printf("\n");
}//voidDisp结束
voidprintstart()
{
printf("-----------------------------------------------------------------------\n");
}
voidWrong()
{
printf("\n输入错误!
\n");
}
voidNofind()
{
printf("\n没有找到该员工!
\n");
}
voidprintc()
{
printf("\t工号\t姓名\t性别\t成绩\t等级\n");
}
voidprinte(Node*p)//用于打印链表中某个节点的数据内容
{
printf("\t%s\t%s\t%s\t%d\t%s\t\n",
p->data.num,p->data.name,p->data.sex,*p->data.sorce,p->data.dj);
}
//用于定位连表中符合要求的结点,并返回该指针
Node*Locate(Linkl,charfindmess[],chargh[])
{
Node*r;
if(strcmp(gh,"num")==0)//按工号查询
{
r=l->next;
while(r!
=NULL)
{
if(strcmp(r->data.num,findmess)==0)//若找到findmess值的工号
returnr;
r=r->next;
}
}
return0;//若未找到,返回一个空指针
}
//add()函数中,无节点时,r指向list头,有节点时,r指向末尾节点
voidAdd(Linkl)//增加员工
{
Node*p,*r,*s;//实现添加操作的临时的结构体指针变量
charnum[10];
intflag=0;
r=l;
s=l->next;//链表没有节点时,s=null;/链表有节点时,指向第一个员工节点
while(r->next!
=NULL)//如果存在后继结点时,r指针后移一个
r=r->next;//将指针移至于链表最末尾,准备添加记录
while
(1)
{
printf("请输入工号(以'0'返回上一级菜单):
");
scanf("%s",num);
if(strcmp(num,"0")==0)//输入'0',跳出while
(1),即跳出add()函数
break;
s=l->next;//每次从第一个节点开始找,看num是否重复。
while(s)//工号重复时,返回主菜单
{
if(strcmp(s->data.num,num)==0)
{
printf("\n提示:
工号为'%s'的员工已经存在,若要修改请你选择'4修改'!
\n",num);
flag=1;
//
return;
}
s=s->next;
}//
p=(Node*)malloc(sizeof(Node));//生成没赋值的新节点p
strcpy(p->data.num,num);
printf("请输入姓名:
");
scanf("%s",p->data.name);
getchar();
printf("请输入性别:
");
scanf("%s",p->data.sex);
getchar();
printf("请输入员工成绩:
");
scanf("%d",&p->data.sorce);
//getchar();
if(*p->data.sorce<=100&&*p->data.sorce>=90)
strcpy(p->data.dj,"优秀");
elseif(*p->data.sorce<90&&*p->data.sorce>=80)
strcpy(p->data.dj,"良好");
elseif(*p->data.sorce<80&&*p->data.sorce>=70)
strcpy(p->data.dj,"中等");
elseif(*p->data.sorce<70&&*p->data.sorce>=60)
strcpy(p->data.dj,"合格");
elseif(*p->data.sorce<60||*p->data.sorce==NULL)
strcpy(p->data.dj,"不合格");
//信息输入已经完成
p->next=NULL;//表明这是链表的尾部结点
r->next=p;//将新建的结点加入链表尾部中
r=p;
saveflag=1;
printc();
printe(p);
Sleep(100);
}//while
(1)
}//voidAdd增加结束
voidDel(Linkl)//删除
{
intsel;
Node*p,*r;//实现删除操作的临时的结构体指针变量
charfindmess[20];
if(!
l->next)//当list无后继结点时,提示和结束返回del()
{
printf("\n\t提示:
没有记录可以删除!
\n");
return;
}
printf("\n\t1按工号删除\n\t2按姓名删除\n");
scanf("%d",&sel);
if(sel==1)//按工号删除
{
printf("请输入要删除的工号:
");
scanf("%s",findmess);
p=Locate(l,findmess,"num");
if(p)
{
r=l;
while(r->next!
=p)
r=r->next;//从第一个结点找起,直到发现r->next=p,是待删除结点,跳出循环
r->next=p->next;//rr->next(p)p->next
free(p);
printf("\n\t提示:
该员工已经成功删除!
\n");
saveflag=1;
}
else
Nofind();//显示一句话
}//if(sel==1)
elseif(sel==2)//按姓名删除
{
printf("请输入要删除的姓名:
");
scanf("%s",findmess);
p=Locate(l,findmess,"name");
if(p)
{
r=l;
while(r->next!
=p)
r=r->next;
r->next=p->next;//rr->next(p)p->next
free(p);
printf("\n\t提示:
该员工已经成功删除!
\n");
saveflag=1;
}
else
Nofind();
}//if(sel==2)
else
Wrong();//显示输入错误的话
}//voidDel删除结束
voidserch(Linkl)//查询功能
{
intsel;
charfindmess[20];
Node*p;//实现查询操作的临时的结构体指针变量
if(!
l->next)
{
printf("\n\t提示:
没有数据可以查询!
\n");
return;
}
printf("请输入要查找的工号:
");
scanf("%s",findmess);
p=Locate(l,findmess,"num");
if(p)
{
printf("\t\t\t\t查找结果\n");
printstart();//打印横线
printc();
printe(p);//打印p结点各个数据成员的值
printstart();//打印横线
}
else
Nofind();
}
voidChange(Linkl)//修改功能
{
Node*p;
charfindmess[20];
if(!
l->next)
{
printf("\n\t提示:
没有资料可以修改!
\n");
return;
}
printf("请输入要修改的员工工号:
");
scanf("%s",findmess);
p=Locate(l,findmess,"num");
if(p)
{
printf("请输入新工号:
");
scanf("%s",p->data.num);
printf("请输入新姓名:
");
scanf("%s",p->data.name);
getchar();
printf("请输入新性别:
");
scanf("%s",p->data.sex);
getchar();
printf("请输入新的员工分数:
");
scanf("%d",&p->data.sorce);
if(*p->data.sorce<=100&&*p->data.sorce>=90)
strcpy(p->data.dj,"优秀");
elseif(*p->data.sorce<90&&*p->data.sorce>=80)
strcpy(p->data.dj,"良好");
elseif(*p->data.sorce<80&&*p->data.sorce>=70)
strcpy(p->data.dj,"中等");
elseif(*p->data.sorce<70&&*p->data.sorce>=60)
strcpy(p->data.dj,"合格");
elseif(*p->data.sorce<60||*p->data.sorce==NULL)
strcpy(p->data.dj,"不合格");
printf("\n\t提示:
数据修改成功!
\n");
//shoudsave=1;
}
else
Nofind();//if(p)结束
}//voidChange(Linkl)//修改功能结束
//插入记录:
按工号查询到要插入的节点的位置,然后在该工号之后插入一个新节点。
voidInsert(Linkl)
{
Node*s,*r,*p;//p指向插入位置,p指新插入记录节点
charch,new_num[10],old_num[10];
//old_num[]保存插入点位置之前的工号,new_num[]保存输入的新记录的工号
intflag=0;
s=l->next;
system("cls");
Disp(l);
while
(1)
{
printf("请你输入已存在的工号(以'0'返回上一级菜单:
)");
scanf("%s",old_num);
if(strcmp(old_num,"0")==0)//输入'0',跳出while
(1),即跳出Insert()函数
return;
s=l->next;//作用?
每次从第一个节点开始找
flag=0;
while(s)//查询该工号是否存在,flag=1表示该工号存在
{
if(strcmp(s->data.num,old_num)==0)
{
flag=1;
break;
}
s=s->next;
}
if(flag==1)
break;//若工号存在,则进行插入之前的新记录的输入操作
else
{
getchar();
printf("\n该工号不存在,时候再次尝试?
(y/n):
",old_num);
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
{continue;}
else
{return;}//回主菜单
}
}//while
(1)
//以下新记录的插入新节点,工号不能跟已存在的工号相同,操作与Add()相同
printf("请你输入待插入的工号(以'0'返回上一级菜单:
)");
scanf("%s",new_num);
if(strcmp(new_num,"0")==0)//输入'0',跳出while
(1),即跳出add()函数
return;
s=l->next;//作用?
每次从第一个节点开始找,看num是否重复。
while(s)//工号重复时,返回主菜单
{
if(strcmp(s->data.num,new_num)==0)
{
printf("提示:
工号为'%s'的员工已经存在'!
\n",new_num);
flag=1;
return;
}
s=s->next;
}//while(s)
p=(Node*)malloc(sizeof(Node));
if(!
p)
{
printf("\n\t错误!
不能申请所需的内存!
");//如没有申请到,打印提示信息
return;//返回主界面
}
strcpy(p->data.num,new_num);
printf("请输入姓名:
");
scanf("%s",p->data.name);
getchar();
printf("请输入性别:
");
scanf("%s",p->data.sex);
getchar();
printf("请输入分数:
");
scanf("%d",&p->data.sorce);
//信息输入已经完成
if(*p->data.sorce<=100&&*p->data.sorce>=90)
strcpy(p->data.dj,"优秀");
elseif(*p->data.sorce<90&&*p->data.sorce>=80)
strcpy(p->data.dj,"良好");
elseif(*p->data.sorce<80&&*p->data.sorce>=70)
strcpy(p->data.dj,"中等");
elseif(*p->dat