这个写的比较冗长,因为刚学完所以写的比较不好
下一个还有一个c++版本写的写的比较简洁
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const char header1[]="-----------------WORKER--------------------------\n";
#define header2 "\n| num | name | hour | time | money |---------\n"
#define header3 "\n"
#define FORMAT "|%-5s|%-5s|%5d |%4d | %4d |\n"
#define DATA p->data.num,p->data.name,p->data.hour,p->data.time,p->data.money
#define END "--------------------------------------\n"
struct worker{
char num[10];
char name[20];
int hour;
int time;
int money;
int mingci;
};
typedef struct node{
struct worker data;
struct node *next;
}Node,*Link;
void Save(Link l){
FILE *fp;
Node *p;
char ch;
int count=0;
fp=fopen("worker.txt","wb+"); //以只写方式
if(fp == NULL){
printf("\n= = = => open file error! \n");
getchar();
return;
}
p=l-> next;
while(p){
if(fwrite(p,sizeof(Node),1,fp) == 1){
p=p->next;
count++;
}
else
break;
}
if(count>0){
getchar();
printf("\n\n\n\n\n = = = = >save file complete ,total saved record number is : %d \n",count);
getchar();
// saveflag=0;
}
else {
system("cls");
printf("the current link is empty,no worker record is saved!\n");
getchar();
}
fclose(fp);
}
void printheader(){
printf(header1);
printf(header2);
printf(header3);
}
void Wrong(){
printf("\n\n\n\n\n*********输入错误,请按任意键继续!*************\n");
getchar();
}
void stringinput(char *t, int lens , char *notice){
char n[255];
int flag=0;
printf(notice);
scanf("%s",&n);
while(strlen(n) > lens){
printf("\n 超过长度,请重新输入\n");
printf(notice);
scanf("%s",&n);
/* if(n<48 || n>95){
printf("输入错误请输入【0~9】");
continue;
}
else flag=1;*/
}
strcpy(t,n);
}
void printfdata(Node *pp){
Node *p;
p=pp;
printf(FORMAT,DATA);
}
int numberinput(char *notice){
int t=0,flag=0;
while(1){
printf(notice);
scanf("%d",&t); //输入工资或者工时
getchar();
if(t<0 || t>99){
printf("输入错误请重新输入:");
getchar();
continue;
}
break;
}
return t;
}
Node *Locateofnum(Link l,char findmess[]){
Node *r;
r=l;
r=r-> next;
while(r){
if(strcmp(r-> data.num,findmess) == 0) //找到findmess的工号
return r;
r=r-> next;
}
return 0;
}
void Nofind(){
printf("\n= = = = =>没有找到这个工人\n");
}
void Locateofname(Link l,char findmess[],Node *n[]){ //按姓名查询
Node *r;
int i=0;
r=l;
r=l->next;
while(r){
if(strcmp(r->data.name,findmess) == 0);
n[i++]=r;
r=r->next;
}
}
void Disp(Link l){ //显示单链表1中储存的工人情况,内容为worker结构中定义的内容
Node *p;
p=l->next; //l存储的是单链表中头结点的指针,该节点没有存储学生信息,指针域指向的后继结点才有学生信息
if(!p){
printf("\n= = = = => 没有工人信息\n");
getchar();
return;
}
printf("\n\n");
printheader();
while(p){
printfdata(p);
p=p->next; //指针移动到下一个节点,开始进行下一批
// printf(header3);
}
getchar();
// getchar();
printf("\n");
}
void Add(Link l){
Node *p,*r,*s; //实现添加操作的临时的结构体指针变量
char ch,flag=0,num[10];
r=l;
s=l->next;
system("cls");
Disp(l);
while(r->next != NULL)
r=r->next;
while(1){ //一次和输入多条,直到工号为0的记录结束添加操作
while(1){
stringinput(num,10,"输入工号(按0返回)");
flag=0;
getchar();
if(strcmp(num,"0") == 0){
printf("是否保存(y/n)?:");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
{Save(l);printf("保存成功");getchar();return;}
else
{printf("按回车键返回");getchar();return;}
getchar();
}
getchar();
// return ;
s=l->next;
while(s){ //查询给学号是否已经存在,若存在则要求输入一个未被占用的工号
if(strcmp(s->data.num,num) == 0){ //若找到学号存在的,提前终止循环
flag=1;
break;
}
s=s->next;
}
if(flag == 1){
getchar();
printf("= == = =>The number %s is existing ,try again?(y/n:)",num);
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
continue;
else{
printf("是否保存(y/n)?:");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y'){
{Save(l);printf("保存成功");getchar();return;}
}
else
{printf("按回车键返回");getchar();return;}
}
// return;
}
else
break;
}
p=(Node *)malloc(sizeof(Node));
if(!p){
printf("\n申请内存失败");
return ;
}
strcpy(p-> data.num,num); //将字符
stringinput(p->data.name,15,"Name:");
p->data.hour=numberinput("每小时工资");
p->data.time=numberinput("每天工作小时数:");
p->data.money=(p->data.hour) * (p->data.time) * 30;
p->data.mingci=0;
p->next=NULL;
r->next=p;
r=p;
// saveflag=1;
}
//return;
printf("是否保存(y/n)?:");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
{Save(l);printf("保存成功");getchar();return;}
else
{printf("按回车键返回");getchar();return;}
}
void menu(){
system("cls");
// printf("欢迎进入员工管理系统\n\n");
printf("\n\n\n\n");
printf(" ********************Menu*******************\n");
printf(" * 1 插入员工 2 删除员工 *\n");
printf(" * 3 查询员工 4 修改员工 *\n");
printf(" * 5 插入员工 6 工资统计 *\n");
printf(" * 7 员工排序 8 员工保存 *\n");
printf(" * 9 显示员工 0 退出系统 *\n");
printf(" *******************************************\n");
}
void shan(Link l){
Node *p,*r;
char findmess[20],ch;
if(! l->next ){
system("cls");
printf("\n= = = = = >没有工人记录\n");
getchar();
return ;
}
system("cls");
Disp(l);
while(1){
stringinput(findmess,10,"输入存在的工人:");
getchar();
p=Locateofnum(l,findmess);
printf("确认要删除 %s (y/n)?",findmess);
scanf("%c",&ch);
if(ch=='y' || ch=='Y'){
if(p){
r=l;
while(r->next!=p)
r=r->next;
r->next=p->next; //将p所指的节点从链表中删去
free(p);
printf("\n= = = =>删除成功 !\n");
//getchar();
// saveflag=1;
}
else
Nofind();
// scanf("%c",&ch);
getchar();
}
/*else
printf("按空格键返回");*/
getchar();//getchar();
printf("是否保存(y/n)?:");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
{Save(l);printf("按回车键返回菜单");getchar();}
else
{printf("按回车键返回菜单");getchar();return;}
}
}
void Find(Link l){
int select; //1.按工号查2.按名字差
char searchinput[20],ch; //保存用户输入查询的内容、
Node *p;
Node *n[5]={NULL}; //用来存放姓名查找的指针
int i=0;
if(!l->next){
system("cls");
printf("没有工人记录");
getchar();
return;
}
system("cls");
while(1){
printf("\n= = = =>1按工号查找 2.按姓名查找\n");
printf(" please choice[1,2]:");
scanf("%d",&select);
if(select == 1){ //按工号查询
stringinput(searchinput,15,"输入已存在的工人工号:");
p=Locateofnum(l,searchinput); //在链表l中查找searchinput的节点,并返回节点的指针
if(p){
printheader();
printfdata(p);
printf(END);
printf(" 请按回车键返回");
getchar();
}
else
Nofind();
getchar();
}
else if(select == 2){
stringinput(searchinput,15,"请输入已存在工人的名字:");
Locateofname(l,searchinput,n); //在链表l中查找姓名为searchinput值的节点,并将节点保存在数组n中
while((p=n[i++]) != NULL){
printheader();
printfdata(p);
printf(END);
}
printf("请按回车键返回");
getchar();
if(n[0] == NULL)
Nofind();
getchar();
}
else
Wrong();
printf("是否继续操作(y/n)\n");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
{printf("按回车键继续");getchar();continue;}
else {printf("按回车键返回菜单");getchar();break;}
}
// getchar();
}
void Change(Link l){
Node *p;
char findmess[20],ch;
if(! l->next){
system("cls");
printf("没有工人记录");
getchar();
return;
}
system("cls");
while(1){
printf("修改工人记录");
stringinput(findmess,10,"输入存在的工人的工号:"); //输入工号并检验
p=Locateofnum(l,findmess); //查询到该节点
if(p){
printf("工号:%s \n",p->data.num);
printf("姓名:%s \n",p->data.name);
stringinput(p->data.name,15,"输入新的名字");
printf("工资/每小时:%d\n",p->data.hour);
p->data.hour=numberinput("工资/每小时(new)");
printf("工时/每天:%d\n",p->data.time);
p->data.time=numberinput("工时/每天(new)");
printf("总工资:\n",p->data.money);
p->data.money=p->data.time * p->data.hour * 30;
p->data.mingci=0;
printf("\n= = = = =>修改成功\n");
// saveflag=1;
}
else
Nofind();
getchar();
printf("是否继续操作(y/n)\n");
scanf("%c",&ch);
if(ch == 'y' || ch == 'Y')
continue;
else break;
}
getchar();
printf("是否保存(y/n)?:");
scanf("%c",&ch);
if(ch == 'y' || ch == 'Y')
Save(l);
else
{printf("按回车键返回菜单!");getchar();getchar();return;}
//getchar();getchar();
}
//利用选择排序法实现单链表的按总工资按总分数段从高到低降序排列
void Sort(Link l){
struct worker temp;
Node *p1,*p2,*p; // p1,p2指向要排序的节点,p指向两个节点中分数较高的一个
int i=0,can;
char ch;
if(l->next == NULL){
system("cls");
printf("====>没有工人记录");
getchar();
return;
Disp(l);
}
system("cls");
Disp(l);
while(1){
printf("请输入[1~3](1:安总工资2:按每小时工资3:按工时:)\n");
scanf("%d",&can);
p1=l->next;
while(p1){
p2=p1->next;
p=p1;
while(p2){
if(can==1 && p2->data.money >= p->data.money)
p=p2;
else if(can == 2 && p2->data.hour >= p->data.hour)
p=p2;
else if(can == 3 && p2->data.time >= p->data.time)
p=p2;
p2=p2->next;
}
temp=p->data;
p->data=p1->data;
p1->data=temp;
p1=p1->next;
}
p=l->next; //已排好序列的头指针给p,准备写名次
while(p != NULL){
i++; //节点序号
p->data.mingci=i; //按名次赋值
p=p->next; //指针后移
}
Disp(l); printf("=====>排序成功\n");
printf("是否继续查询(y/n)?");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
continue;
else
{printf("按回车键返回菜单!");getchar();break;}
// getchar();
}
// saveflag=1;
}
void Insert(Link l){
Link p,v,newinfo; //p指向插入的位置,newinfo指新插入的记录
char ch,num[10],s[10]; //s[]保存插入点位置之前的工号,num[]保存输入新纪录的工号
int flag=0;
v=l->next;
system("cls");
Disp(l);
while(1){
while(1){
while(1){
stringinput(s,10,"请输入在哪个工号后面插入:");
flag=0;
v=l->next;
while(v){ //查询该学号是否存在,flag=1表示该工号存在
if(strcmp(v->data.num,s) == 0){
flag=1;
break;
}
v=v->next;
}
if(flag == 1)
break; //若工号存在,则进行插入之前的新纪录的输入操作
else{
getchar();
printf("\n=====>%s 这个工号不存在,查实再输一次?(y/n):",s);
scanf("%c",&ch);
if(ch == 'y'|| ch == 'Y'){
continue;
}
else break;
}
}
stringinput(num,15,"请输入新的工号:");
v=l->next;
while(v){
if(strcmp(v->data.num,num) == 0){ //表示找到了相同的工号,
printf("=====>对不起,%s这个工号是存在的!\n",num);
printheader();
printfdata(v);
printf("\n");
getchar();
getchar();
return;
}
v=v->next;
}
newinfo=(Node *)malloc(sizeof(Node));
if(!newinfo){
printf("\n 申请内存失败");
return;
}
strcpy(newinfo->data.num,num);
stringinput(newinfo->data.name,15,"Name:");
newinfo->data.hour=numberinput("工资/每小时:");
newinfo->data.time=numberinput("工时/每天:");
newinfo->data.money=newinfo->data.time * newinfo->data.hour * 30;
newinfo->data.mingci=0;
newinfo->next=NULL;
// saveflag=1;
p=l->next; //p指向实际保存着工人的记录的第一个节点
while(1){
if(strcmp(p->data.num,s) == 0){
newinfo->next=p->next;
p->next=newinfo;
break;
}
p=p->next;
}
Disp(l);
printf("\n\n");
getchar();
printf("是否继续操作(y/n)\n");
scanf("%c",&ch);
if(ch == 'y' || ch == 'Y')
continue;
else break;
}
getchar();
printf("是否保存(y/n)?:");
scanf("%c",&ch);getchar();
if(ch == 'y' || ch == 'Y')
{printf("保存成功!");getchar();Save(l);break;}
else
{printf("按回车键返回主菜单!");getchar();return;}
getchar();
}
}
void Count(Link l){
//Node *pe; //用于指向分数最高的节点
Node *r=l->next;
int count[4]={0}; //保存总工资出项各个分数段的人数
if(! r){
system("cls");\
printf("= = = =>没有工人记录!\n");
getchar();
return;
}
system("cls");
Disp(l);
//pe=r;
while(r){
if(r->data.money<3600)
count[0]++;
if(r->data.money>=3600 && r->data.money<4800)
count[1]++;
if(r->data.money>=4800 && r->data.money<6000)
count[2]++;
if(r->data.money >= 6000)
count[3]++;
r=r->next;
}
printf("\n-------------统计结果--------------\n");
printf("总工资在0~3600:%d (人/天)\n",count[0]);
printf("总工资在3600~4800:%d(人/天)\n",count[1]);
printf("总工资在4800~6000:%d(人/天)\n",count[2]);
printf("总工资>6000: %d(人/天)\n",count[3]);
printf("\n---------------------------------\n");
printf("\n按任意键返回!");
getchar();
//getchar();
}
int main()
{
Link l; //定义链表
FILE *fp; //定义一个文件指针
int select; //保存选择变量的结果
char ch; //保存(y,Y,N,n)
int count=0; //保存文件中的记录条数
Node *p,*r; //定义记录指针变量
l=(Node *)malloc(sizeof(Node));
if(!l){
printf("\n 申请内存失败");
// return ;
}
l->next=NULL;
r=l;
fp=fopen("worker.txt","ab+");
if(fp == NULL){
printf("\n= = = = >不能打开文件 \n");
exit(0);
}
while(!feof(fp))
{
p=(Node *)malloc(sizeof(Node));
if(fread(p,sizeof( Node),1,fp) == 1)
{
p->next=NULL; //2015==NULL
r->next=p; //2015=2014
r=p; //2014=2014
count++;
}
}
fclose(fp); //关闭文件
/*printf("\n = = = = >打开文件成功,记录的次数是:%d",count);
printf("\n = = = =>按任意键返回菜单!");*/
printf("欢迎进入员工管理系统\n\n\n");
printf("按回车键进入菜单");
getchar();
int flag=0;
while(1)
{
system("cls");
menu();
p=r;
printf("\n 请按下你的选择(0~9):");
scanf("%d",&select);
if(select == 0)
{
// if(saveflag == 1)
//{
getchar();
printf("\n = = = ==> 是否保存修改的文件?(y/n):");
scanf("%c",&ch);
if(ch == 'y' || ch == 'Y')
{
Save(l);
}
printf("= = == = >谢谢你的使用!");
getchar();
break;
// }
}
switch(select)
{
case 1:Add(l);break;
case 2:shan(l);break;
case 3:Find(l);break; //查询
case 4:Change(l);break; //修改
case 5:Insert(l);break;
case 6:Count(l);break; //统计
case 7:Sort(l);break; //排序
case 8:Save(l);break;
case 9:system("cls");Disp(l);getchar();break;
case 0:flag=1;break;
default:Wrong();getchar();break; //按键错误 必须输入数值为0~9;
}
if(flag)
break;
}
return 0;
}