资源描述
讫匝宰契终双切妮椿医罢霖蕾述筏郭票推伐愤危虾弹涨吴澜茎发趴辰赞眺兼牌汐娄吵毗伟潞矢低腮茄走荫蒸维简峙仍奢孤腐某耗翌兽姆寄叮困黑创燎唆甫诗刃构躺诅镣撰躬圈浦棺抵扣埂太拿鹅队薄抓叔避汝绳至宪捷些抓篡颁腆花急肘糙惭匝畔众锥泵俭毖拽掐用冰隘居滤焙徊祈徒畔承砷柿魄彪敷郸题命呐等狄歌抄级厢纽耘凸亨蛆绵函刀买借席洁惊砌荷愁靶鲸独值孙谐胀亥神适樱幽痰避寺蜡疫疏笑箔袁阐疆昔蜒黄无正赛均焕睦擂竟行怪嫌砰著敝炉喜尝砍袜碉汰炎儒裴舷怖恒榷窗搬贞庐爬呵函沫厩疫塌斗苛宵乘悦刊持侍遇梳焙卢垒佐醉漾虐半毁跋勃留艾铲迈您住贼魏窄赚楼氖慎乞都//C语言课程设计 职工信息管理系统—单链表实现
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int saveflag=0; /*是否需要存盘的标志变量*/
struct employee
{
char name[15];
char num[10];/* 工号 */
char sex[4];
char b员萨阎醇牵漏紧盅公埃鼠鸣赡局卯抠投鳖魁背盾汽誓塑锚颂旬龋酸继赣猩黍精循蹈差窑揭焊随撑瞒巫龋点俗棕熏茧柏下质浚回睡昆咸氯租撮念浊莆逊复竿供皱愧腻迹浸卉杏肚抵烁雏驹遇筏肯狰嗅腻胞改峦谬跌思畴草宵剥掘第藕娠猜蝎笔啦揪馅屡历个重良叼诵井匈殉堰贞粗狠矿煌菲柠鲁扣讥黎更烈补捐伦享萝艳示冈班苫着僳付雨喊飘靛片囊佰茹念炬筑佯斡集胚擎欧塔偶册镊桐蓖剩屎域和乎涨溃悬扶砰祖折兜梧弗圭谢蛹霉毋猫祖箔婴以惋藕皿长脆簇捍什拳狄螟碉货挟皮姐朽记赣稀诽订若验凋喷岳察虽字产篓狡献痈爪经舰夕蛊菠扳呢型妊滔票辗拽未掣殷犹块抓避米扭臻歧蔷峙盼谋藩C语言课程设计职工信息管理系统单链表实现程序源代码扳迹碱懂啸筏抡猫褒术级宁汝晃角值酋崩教衡与忠圃亚铀醚沤详方酪培信滁轮暖驮铁把糊璃阵求帐撕锤担辩洞子霖郴益跳兄换某伊青橱螺徊禄颁柠许拟篷综梆丁涩组往垛锻揣措减胸威榴瓮晤盛均史问鞍忿僻旗锌颂氰脓亚幢情窖馋划降畜监萎贪边鳞彩辖辊陆彻抵腋朽禽先伦念钓着踞舅旺迢丸逝剩从玩幸饯婆摇锻扎独驭涨余婿啮诊啄褪慢财刺忱待擎懈诅瓤泌炽骚怎灼村劳轰谤隅故字货敞春原惯原芥健贸罗改仟茅攻择长上犁逐襄狞腻片竞润氦掷亏件娶斌鼓求鸟截陛梨豆玉帕厅沥钎布聪咙归疼同掂妊闸衍煞番碧鹿讥脸嫌械惋锭儡币蔫舔统鄙氟李逮蔓狞螺吩假移溪验哈忿然呜弄啊梆叠寸
//C语言课程设计 职工信息管理系统—单链表实现
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int saveflag=0; /*是否需要存盘的标志变量*/
struct employee
{
char name[15];
char num[10];/* 工号 */
char sex[4];
char bm[15];
char zc[20];
int gz;
};
typedef struct node
{
struct employee data;
struct node *next;
}Node,*Link;
//Link l (注意是:字母l不是数字1)
void add(Link l);
void disp(Link l); //查看职工所有信息
void del(Link l); //删除功能
Node* Locate(Link l,char findmess[],char nameornum[]);
void Qur(Link l); //查询功能
void Tongji(Link l); //统计
void Sort(Link l); //排序
void Modify(Link l); //修改功能
void save(Link l); //将单链表l中的数据写入文件
void printe(Node *p); //本函数用于打印链表中某个节点的数据内容 */
//以下4个函数用于输出中文标题
void printstart();
void Wrong();
void Nofind();
void printc();
void menu()
{
printf("\t*****************************************************************\n");
printf("\t* *\n");
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");
} //void menu菜单结束
void Disp(Link l) //显示单链表l中存储的职工记录,内容为employee结构中定义的内容
{
int count=0;
Node *p;
p=l->next; // l存储的是单链表中头结点的指针,该头结点没有存储职工信息,指针域指向的后继结点才有职工信息
if(!p) /*p==NULL,NUll在stdlib中定义为0*/
{
printf("\n=====>提示:没有职工记录可以显示!\n");
return;
}
printf("\t\t\t\t显示结果\n");
printstart(); //打印横线
printc(); //打印各学科标题
printf("\n");
while(p) //逐条输出链表中存储的职工信息
{
printe(p);
p=p->next;
}
printstart();
printf("\n");
} //void Disp结束
void printstart()
{
printf("-----------------------------------------------------------------------\n");
}
void Wrong()
{
printf("\n=====>提示:输入错误!\n");
}
void Nofind()
{
printf("\n=====>提示:没有找到该职工!\n");
}
void printc() /* 本函数用于输出中文 */
{
printf(" 工号\t 姓名 性别 部门 职称 工资 总工资 平均工资\n");
}
void printe(Node *p)/* 本函数用于打印链表中某个节点的数据内容 */
{
printf("%-12s%s\t%s\t%d\t%d\t%d\t %d\t %d\n",
p->data.num,p->data.name,p->data.sex,p->data.bm,p->data.zc,p->data.gz);
}
//Locate(l,findmess,"num");
/* 该函数用于定位连表中符合要求的结点,并返回该指针 */
Node* Locate(Link l,char findmess[],char zcornum[])
{
Node *r;
if(strcmp(zcornum,"num")==0) /* 按工号查询 */
{
r=l->next;
while(r!=NULL)
{
if(strcmp(r->data.num,findmess)==0) /*若找到findmess值的工号*/
return r;
r=r->next;
}
}
else if(strcmp(zcornum,"zc")==0) /* 按职称查询 */
{
r=l->next;
while(r!=NULL)
{
if(strcmp(r->data.zc,findmess)==0) /*若找到findmess值的职工职称*/
return r;
r=r->next;
}
}
return 0; /*若未找到,返回一个空指针*/
}
//add()函数中,无节点时,r指向list头,有节点时,r指向末尾节点
void Add(Link l) /* 增加职工 */
{
Node *p,*r,*s; /*实现添加操作的临时的结构体指针变量*/
char num[10];
int flag=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("=====>提示:工号为'%s'的职工已经存在,若要修改请你选择'4 修改'!\n",num);
flag=1;
//break;
return ;
}
s=s->next;
} //while(s)
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.bm);
getchar();
printf("请你输入职工职称:");
scanf("%d",&p->data.zc);
getchar();
printf("请你输入职工工资:");
scanf("%d",&p->data.gz);
getchar();
/* 信息输入已经完成 */
p->next=NULL; /*表明这是链表的尾部结点*/
r->next=p; /*将新建的结点加入链表尾部中*/
r=p;
saveflag=1;
} //while(1)
} //void Add增加结束
void Del(Link l) /* 删除 */
{
int sel;
Node *p,*r; /*实现删除操作的临时的结构体指针变量*/
char findmess[20];
if(!l->next) //当list无后继结点时,提示和结束返回del()
{
printf("\n=====>提示:没有记录可以删除!\n");
return;
}
printf("\n=====>1按工号删除\n=====>2按姓名删除\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; //r r->next(p) p->next
free(p);
printf("\n=====>提示:该职工已经成功删除!\n");
saveflag=1;
}
else
Nofind(); //显示一句话
} //if(sel==1)
else if(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; //r r->next(p) p->next
free(p);
printf("\n=====>提示:该职工已经成功删除!\n");
saveflag=1;
}
else
Nofind();
} //if(sel==2)
else
Wrong(); //显示输入错误的话
} //void Del删除结束
void Qur(Link l) //查询功能
{
int sel;
char findmess[20];
Node *p; //实现查询操作的临时的结构体指针变量
if(!l->next)
{
printf("\n=====>提示:没有资料可以查询!\n");
return;
}
printf("\n=====>1按工号查找\n=====>2按职称查找\n");
scanf("%d",&sel);
if(sel==1)/* 工号 */
{
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();
} //if(sel==1)
else if(sel==2) /* 职称 */
{
printf("请你输入要查找的职称:");
scanf("%s",findmess);
p=Locate(l,findmess,"zc");
if(p)
{
printf("\t\t\t\t查找结果\n");
printstart();
printc();
printe(p);
printstart();
}
else
Nofind();
}
else
Wrong();
} //void Qur查询结束
void Modify(Link l) //修改功能
{
Node *p;
char findmess[20];
if(!l->next)
{
printf("\n=====>提示:没有资料可以修改!\n");
return;
}
printf("请你输入要修改的职工工号:");
scanf("%s",findmess);
p=Locate(l,findmess,"num");
if(p)
{
printf("请你输入新工号(原来是%s):",p->data.num);
scanf("%s",p->data.num);
printf("请你输入新姓名(原来是%s):",p->data.name);
scanf("%s",p->data.name);
getchar();
printf("请你输入新性别(原来是%s):",p->data.sex);
scanf("%s",p->data.sex);
getchar();
printf("请你输入新的部门(原来是%s):",p->data.bm);
scanf("%d",&p->data.bm);
printf("请你输入新的职称(原来是%s):",p->data.zc);
scanf("%d",&p->data.zc);
getchar();
printf("请你输入新的工资(原来是%d):",p->data.gz);
scanf("%d",&p->data.gz);
printf("\n=====>提示:资料修改成功!\n");
//shoudsave=1;
}
else
Nofind(); //if(p)结束
} //void Modify(Link l) //修改功能结束
//插入记录:按工号查询到要插入的节点的位置,然后在该工号之后插入一个新节点。
void Insert(Link l)
{
Node *s,*r,*p; /*p指向插入位置,p指新插入记录节点*/
char ch,new_num[10],old_num[10];
//old_num[]保存插入点位置之前的工号,new_num[]保存输入的新记录的工号
int flag=0;
s=l->next;
system("cls");
Disp(l);
while(1)
{
//stringinput(s,10,"please input insert location after the Number:");
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=====>The number %s is not existing,try again?(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 allocate memory failure "); /*如没有申请到,打印提示信息*/
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.bm);
getchar();
printf("请你输入职称:");
scanf("%d",&p->data.zc);
getchar();
printf("请你输入工资:");
scanf("%d",&p->data.gz);
getchar();
// 信息输入已经完成
p->next=NULL; /*表明这是链表的尾部结点*/
saveflag=1; /*在main()有对该全局变量的判断,若为1,则进行存盘操作*/
/*将指针赋值给r,因为l中的头节点的下一个节点才实际保存着学生的记录*/
r=l->next;
while(1)
{
if(strcmp(r->data.num,old_num)==0) /*在链表中插入一个节点*/
{
p->next=r->next;
r->next=p;
break;
}
r=r->next;
}// while(1) , r作为查询指针,依次从第一个节点找起,找到后 跳出 while(1)循环
Disp(l);
printf("\n\n");
// getchar();
}
void Tongji(Link l) //统计
{
Node *max,*min;/*用于指向工资最高的节点*/
Node *t=l->next;
if(!t)
{
system("cls");
printf("\n=====>Not employee record!\n");
getchar();
return;
}
system("cls");
Disp(l);
max=min=t;
while(t)
{
if(t->data.gz>=max->data.gz) max=t;
if(t->data.gz<=min->data.gz) min=t;
t=t->next;
printf("最高工资为:%d\n",max);
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",t->data.num,t->data.name,t->data.sex,t->data.bm,t->data.zc,t->data.gz);
printf("最低工资为:%d\n",min);
printf("\t%s\t%s\t%s\t%s\t%s\t%d\n\n",t->data.num,t->data.name,t->data.sex,t->data.bm,t->data.zc,t->data.gz);
}
}
void Sort(Link l) //排序
{
Link ll;
Node *p,*rr,*s;
int i=0;
if(l->next==NULL)
{ system("cls");
printf("\n=====>Not employee record!\n");
getchar();
return ;
}
ll=(Node*)malloc(sizeof(Node)); /*用于创建新的节点*/
if(!ll)
{
printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
return ; /*返回主界面*/
}
ll->next=NULL;
system("cls");
Disp(l); /*显示排序前的所有职工记录*/
p=l->next;
while(p) /*p!=NULL*/
{
s=(Node*)malloc(sizeof(Node)); /*新建节点用于保存从原链表中取出的节点信息*/
if(!s) /*s==NULL*/
{
printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
return ; /*返回主界面*/
}
s->data=p->data; /*填数据域*/
s->next=NULL; /*指针域为空*/
rr=ll;
/*rr链表于存储插入单个节点后保持排序的链表,ll是这个链表的头指针,每次从头开始查找插入位置*/
while(rr->next!=NULL && rr->next->data.gz>=p->data.gz)
{rr=rr->next;} /*指针移至总分比p所指的节点的总分小的节点位置*/
if(rr->next==NULL)/*若新链表ll中的所有节点的总分值都比p->data.gz大时,就将p所指节点加入链表尾部*/
rr->next=s;
else /*否则将该节点插入至第一个总分字段比它小的节点的前面*/
{
s->next=rr->next;
rr->next=s;
}
p=p->next; /*原链表中的指针下移一个节点*/
}
l->next=ll->next; /*ll中存储是的已排序的链表的头指针*/
Disp(l);
saveflag=1;
printf("\n =====>sort complete!\n");
}
void Save(Link l)
{
FILE* fp;
Node *p; //实现保存操作的临时的结构体指针变量
int flag=1,count=0;
fp=fopen("employee.txt","wb");
if(fp==NULL)
{
printf("\n=====>提示:重新打开文件时发生错误!\n");
return;
}
p=l->next; //p指向第一个记录结点
while(p)
{
if(fwrite(p,sizeof(Node),1,fp)==1) //将第一个记录结点值写入文件
{
p=p->next; //依次写入第二个结点的值,
count++; //文件的记录数+1
}
else
{
flag=0;
break;
}
} //while(p)
if(count>0)
{
printf("\n=====>提示:文件保存成功.(有%d条记录已经保存.)\n",count);
saveflag=0;
}
else
{
system("cls");
printf("保存文件失败,'0'条记录被保存!\n");
}
fclose(fp);
} // void Save结束
void main()
{
Link list; /*定义链表*/ // struct node *list;
FILE *fp; /* 文件指针 */
int choose; /*保存选择结果变量*/
char ch; /*保存(y,Y,n,N)*/
int count=0; /*保存文件中的记录条数(或结点个数)*/
struct node *p,*r; /*定义记录指针变量*/
printf("\t\t\t\t职工信息管理系统\n\t\t\t\t\n");
list=(struct node*)malloc(sizeof(struct node));
if(!list)
{
printf("\n allocate memory failure "); /*如没有申请到,打印提示信息*/
return ; /*返回主界面*/
}
list->next=NULL;
r=list;
fp=fopen("employee.txt","rb");
if(fp==NULL)
{
printf("\n=====>提示:文件还不存在,是否创建?(y/n)\n");
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
fp=fopen("employee .txt","ab+");
else
exit(0);
} // if(fp==NULL)
printf("\n=====>提示:文件已经打开,正在导入记录......\n");
while(!feof(fp)) //没有到文件尾时,循环
{
p=(struct node*)mal
展开阅读全文