很久以前的作业,现在想起来还是发到博客上来吧,可能会或多或少的帮助到别人。第一次在实际应用中用到链表,刚开始时遇到了一些难题,而且时间也比较紧,没有刻意考虑代码的可读性。
//基于链表和文件操作的员工信息管理系统
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
#define Head1 " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n"
#define Head2 " ┃ 员工信息 ┃\n"
#define Head4 " ┃ 员工工资分布统计 ┃\n"
#define Head3 " ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n"
#define Data " ┃ 姓名 工号 工资(元/时) 工时(时/日) 总工资(元) ┃\n"
#define Frame " ┃ ┃\n"
#define StaffD " ┃%10s%9s%13d%13d%15d ┃\n"
#define Tail " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n"
char Error_Memory[]="内存分配失败";
char Error_File[]="文件打开失败";
char Error_Find[]="未找到该员工";
char Error_Input[]="该工号已存在";
char Success_Save[]="信息保存成功";
char Mul_Find[]="发现重名员工";
struct Staff
{
char name[30];
char num[10];
int salary;
int work_hour;
int Sum_Salary;
};
typedef struct node
{
struct Staff person;
struct node *next;
}Node,*List;
List first;//链表首节点
Node *now,*previous;
int count;
void Input();//员工信息输入
void Delete();//员工信息输删除
void Modify();//员工信息修改
void Output();//员工信息查询
void Sort();//节点排序入口
void Sort_S(int,int);//排序具体实现函数
void Count();//分段统计员工数量
void Open_File();//打开文件
void Save();//保存
void Return();//返回
void Prompt(char *);//打印提示信息
void Query_Narrow(int);//精确查找
void Query_Wider();//范围查找
int Make_Num(char *);//字符串转化为数字
int main()
{
int select;
while(select)
{
system("cls");
printf(" 欢迎进入员工信息管理系统!\n\n");
printf(" ╔═══════════════主菜单════════════════╗\n");
printf(" ║ ║\n");
printf(" ║ 1.员工信息输入 ║\n");
printf(" ║ ║\n");
printf(" ║ 2.员工信息删除 ║\n");
printf(" ║ ║\n");
printf(" ║ 3.员工信息修改 ║\n");
printf(" ║ ║\n");
printf(" ║ 4.员工信息查询 ║\n");
printf(" ║ ║\n");
printf(" ║ 5.员工信息排序 ║\n");
printf(" ║ ║\n");
printf(" ║ 6.员工信息统计 ║\n");
printf(" ║ ║\n");
printf(" ║ 0.退出系统 ║\n");
printf(" ║ ║\n");
printf(" ╚══════════════════════════════════╝\n\n");
printf("请输入您的选择<0~6>:");
scanf("%d",&select);
switch(select)
{
case 1:
Input();break;
case 2:
Delete();break;
case 3:
Modify();break;
case 4:
Output();break;
case 5:
Sort();break;
case 6:
Count();break;
default:
break;
}
}
return 0;
}
void Open_File()//打开文件
{
FILE *fp;
count=0;
first=(Node *)malloc(sizeof(Node));
if(first==0)
{
Prompt(Error_Memory);
Return();
return ;
}
first->next=NULL;
previous=first;
fp=fopen("staff.txt","r+");
if(fp==NULL)
{
Prompt(Error_File);
Return();
exit(0);
}
while(!feof(fp))
{
now=(Node *)malloc(sizeof(Node));
if(now==0)
{
Prompt(Error_Memory);
Return();
return ;
}
if(count==0)
first->next=now;
if(fread(now,sizeof(Node),1,fp)==1)
{
previous->next=now;
now->next=NULL;
previous=now;
count++;
}
}
getchar();
fclose(fp);
}
void Save()//保存链表中的数据至文件中
{
FILE *fp;
now=first->next;
fp=fopen("staff.txt","w");
if(fp==NULL)
{
Prompt(Error_File);
Return();
exit(0);
}
while(now!=NULL)
{
if(fwrite(now,sizeof(Node),1,fp)==1)
{
now=now->next;
}
}
fclose(fp);
system("cls");
printf("主菜单-->输入员工信息->操作结果\n\n\n");
Prompt(Success_Save);
}
void Return()//返回主页面
{
getchar();
getchar();
}
void Prompt(char *message)//打印提示信息
{
printf(" ╭──────────────────╮\n");
printf(" │ │\n");
printf(" │ %17s │\n",message);
printf(" │ │\n");
printf(" ╰──────────────────╯\n");
Return();
}
int Make_Num(char *str)//讲字符串转化为数字
{
int i,sum=0,f=1;
for(i=strlen(str)-1;i>=0;i--,f*=10)
{
sum+=((str[i]-'0')*f);
}
return sum;
}
void Query_Narrow(int select)//精确查找
{
int cnt=0;
char require[30];
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
now=first->next;
system("cls");
printf("主菜单-->输入查询条件\n\n");
printf(" ╭──────────────────╮\n");
printf(" │ │\n");
if(select==1)
{
printf(" │ %19s │\n","请输入员工工号");
}
else if(select==2)
{
printf(" │ %19s │\n","请输入员工姓名");
}
printf(" │ │\n");
printf(" ╰──────────────────╯\n\n");
printf(" ");
scanf("%s",require);
system("cls");
printf("主菜单-->输入查询条件->查询结果\n\n");
printf(Head1);
printf(Head2);
printf(Head3);
printf(Data);
while(now!=NULL)
{
if(select==1)
{
if(strcmp(now->person.num,require)==0)
{
printf(Head3);
printf(Frame);
printf(StaffD,now->person.name,now->person.num,now->person.salary,now->person.work_hour,now->person.Sum_Salary);
printf(Frame);
cnt++;
}
}
else if(select==2)
{
if(strcmp(now->person.name,require)==0)
{
printf(Head3);
printf(Frame);
printf(StaffD,now->person.name,now->person.num,now->person.salary,now->person.work_hour,now->person.Sum_Salary);
printf(Frame);
cnt++;
}
}
now=now->next;
}
if(cnt==0)
{
printf(Head3);
printf(Frame);
printf(" ┃ 未找到该员工 ┃\n");
printf(Frame);
}
printf(Tail);
getchar();
}
void Query_Wider()//条件查找
{
int cnt=0,tempN,Sal_min=-1,Sal_max=-1,WoH_min=-1,WoH_max=-1,SuS_min=-1,SuS_max=-1,flag;
char tempS[10];
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
now=first->next;
system("cls");
printf("主菜单-->输入查询条件\n\n");
printf(" 请输入筛选条件(若无要求则输入回车)\n");
printf(" 工资(下限):");
gets(tempS);
tempN=Make_Num(tempS);
if(tempN!=0)
Sal_min=tempN;
printf(" 工资(上限):");
gets(tempS);
tempN=Make_Num(tempS);
if(tempN!=0)
Sal_max=tempN;
printf(" 工时(下限):");
gets(tempS);
tempN=Make_Num(tempS);
if(tempN!=0)
WoH_min=tempN;
printf(" 工时(上限):");
gets(tempS);
tempN=Make_Num(tempS);
if(tempN!=0)
WoH_max=tempN;
printf(" 总工资(下限):");
gets(tempS);
tempN=Make_Num(tempS);
if(tempN!=0)
SuS_min=tempN;
printf(" 总工资(上限):");
gets(tempS);
tempN=Make_Num(tempS);
if(tempN!=0)
SuS_max=tempN;
system("cls");
printf("主菜单-->输入查询条件->查询结果\n\n");
printf(Head1);
printf(Head2);
printf(Head3);
printf(Data);
while(now!=NULL&&count)
{
flag=1;
if(flag&&Sal_min!=-1&&now->person.salary<Sal_min)
{
flag=0;
}
if(flag&&Sal_max!=-1&&now->person.salary>Sal_max)
{
flag=0;
}
if(flag&&WoH_min!=-1&&now->person.work_hour<WoH_min)
{
flag=0;
}
if(flag&&WoH_max!=-1&&now->person.work_hour>WoH_max)
{
flag=0;
}
if(flag&&SuS_min!=-1&&now->person.Sum_Salary<SuS_min)
{
flag=0;
}
if(flag&&SuS_max!=-1&&now->person.Sum_Salary>SuS_max)
{
flag=0;
}
if(flag)
{
printf(Head3);
printf(Frame);
printf(StaffD,now->person.name,now->person.num,now->person.salary,now->person.work_hour,now->person.Sum_Salary);
printf(Frame);
cnt++;
}
now=now->next;
}
if(cnt==0)
{
printf(Head3);
printf(Frame);
printf(" ┃ 未找到该员工 ┃\n");
printf(Frame);
}
printf(Tail);
}
void Sort_S(int select1,int select2)//将链表中的内容排序(select1为排序依据,select2为升/降序)
{
int flag;
Node *i,*j,*temp;
temp=first->next;
i=first->next;
while(i!=NULL)
{
j=first->next;
while(j!=NULL)
{
flag=0;
if(select1==1)
{
if((select2==1&&i->person.salary>j->person.salary)||(select2==2&&i->person.salary<j->person.salary))
{
flag=1;
}
}
else if(select1==2)
{
if((select2==1&&i->person.work_hour>j->person.work_hour)||(select2==2&&i->person.work_hour<j->person.work_hour))
{
flag=1;
}
}
else if(select1==3)
{
if((select2==1&&i->person.Sum_Salary>j->person.Sum_Salary)||(select2==2&&i->person.Sum_Salary<j->person.Sum_Salary))
{
flag=1;
}
}
if(flag)
{
swap(i->person.name,j->person.name);
swap(i->person.num,j->person.num);
swap(i->person.salary,j->person.salary);
swap(i->person.work_hour,j->person.work_hour);
swap(i->person.Sum_Salary,j->person.Sum_Salary);
}
j=j->next;
}
i=i->next;
}
system("cls");
printf("主菜单-->选择排序方式->排序结果\n\n");
printf(Head1);
printf(Head2);
printf(Head3);
printf(Data);
while(temp!=NULL)
{
printf(Head3);
printf(Frame);
printf(StaffD,temp->person.name,temp->person.num,temp->person.salary,temp->person.work_hour,temp->person.Sum_Salary);
printf(Frame);
temp=temp->next;
}
printf(Tail);
Return();
}
void Input()//遍历链表找到对应员工并输出
{
int f;
Node *temp;
char input='Y';
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
while(input=='Y'||input=='y')
{
now=(Node *)malloc(sizeof(Node));
if(now==0)
{
Prompt(Error_Memory);
Return();
return ;
}
system("cls");
printf("主菜单-->输入员工信息\n\n\n");
printf(" ╭──────────────────╮\n");
printf(" │ 当前员工数量:%3d │\n",count);
printf(" ╰──────────────────╯\n\n");
printf(" 员工姓名:");
scanf("%s",now->person.name);
printf(" 员工工号:");
scanf("%s",now->person.num);
printf(" 员工工资(元/时):");
scanf("%d",&now->person.salary);
printf(" 员工工时(时/日):");
scanf("%d%*c",&now->person.work_hour);
now->person.Sum_Salary=now->person.salary*now->person.work_hour*30;
f=0;
temp=first->next;
while(temp!=NULL)
{
if(strcmp(temp->person.num,now->person.num)==0)
{
system("cls");
printf("主菜单-->输入员工信息\n\n\n");
Prompt(Error_Input);
printf("\n\n输入失败!是否重新输入?(y/n)");
scanf("%c",&input);
f=1;
break;
}
temp=temp->next;
}
if(f)
continue;
previous->next=now;
now->next=NULL;
previous=now;
count++;
printf("\n\n输入完成!是否继续输入?(y/n)");
scanf("%c",&input);
}
Save();
}
void Delete()//删除链表内一节点
{
int i,flag;
char delet='Y',temp[50];
Node *location[5000][2];
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
while(delet=='Y'||delet=='y')
{
system("cls");
printf("主菜单-->输入员工信息\n\n\n");
printf(" ╭───────────────────────╮\n");
printf(" │ 请输入要删除的员工姓名或工号 │\n");
printf(" ╰───────────────────────╯\n\n");
printf(" ");
scanf("%s",temp);
now=first->next;
previous=first;
flag=0;
while(now!=NULL)
{
if(strcmp(now->person.name,temp)==0||strcmp(now->person.num,temp)==0)
{
location[flag][0]=previous;
location[flag][1]=now;
flag++;
}
previous=now;
now=now->next;
}
if(flag==0)
{
system("cls");
printf("主菜单-->输入员工信息-->查询结果\n\n\n");
Prompt(Error_Find);
printf("\n\n员工不存在!是否继续删除?(y/n)");
scanf("%c",&delet);
}
else
{
system("cls");
printf("主菜单-->输入员工信息-->查询结果\n\n\n");
printf(" 已找到员工! \n");
if(flag>1)
{
printf(" ╭──────────────────╮\n");
printf(" │ │\n");
printf(" │ %17s │\n",Mul_Find);
printf(" │ │\n");
printf(" ╰──────────────────╯\n\n");
printf(" 请输入工号以确认员工唯一\n");
printf(" ");
scanf("%s",temp);
for(i=0;i<flag;i++)
{
if(strcmp(location[i][1]->person.num,temp)==0)
break;
}
system("cls");
printf("主菜单-->输入员工信息-->查询结果\n\n\n");
if(i==flag)
{
Prompt(Error_Find);
printf("\n\n员工不存在!是否继续删除?(y/n)");
scanf("%c",&delet);
continue;
}
}
else if(flag==1)
{
i=flag-1;
}
printf(Head1);
printf(" ┃ 再看看它最后一眼吧 ┃\n");
printf(Head3);
printf(Data);
printf(Head3);
printf(Frame);
printf(StaffD,location[i][1]->person.name,location[i][1]->person.num,location[i][1]->person.salary,location[i][1]->person.work_hour,location[i][1]->person.Sum_Salary);
printf(Frame);
printf(Tail);
location[i][0]->next=location[i][1]->next;
free(location[i][1]);
printf("\n\n删除完成!是否继续删除?(y/n)");
getchar();
scanf("%c",&delet);
}
}
Return();
Save();
}
void Modify()//修改链表内某一节点
{
int flag,flagg;
char modify='Y',temp[50];
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
while(modify=='Y'||modify=='y')
{
system("cls");
printf("主菜单-->输入员工信息\n\n\n");
printf(" ╭───────────────────────╮\n");
printf(" │ 请输入要修改的员工姓名或工号 │\n");
printf(" ╰───────────────────────╯\n\n");
printf(" ");
scanf("%s",temp);
now=first->next;
flag=0;
while(now!=NULL)
{
if(strcmp(now->person.name,temp)==0||strcmp(now->person.num,temp)==0)
{
flag++;
}
now=now->next;
}
if(flag==0)
{
system("cls");
printf("主菜单-->输入员工信息-->查询结果\n\n\n");
Prompt(Error_Find);
printf("\n\n员工不存在!是否继续修改?(y/n)");
scanf("%c",&modify);
}
else
{
system("cls");
printf("主菜单-->输入员工信息-->查询结果\n\n\n");
printf(" 已找到员工! \n");
if(flag>1)
{
printf(" ╭──────────────────╮\n");
printf(" │ │\n");
printf(" │ %17s │\n",Mul_Find);
printf(" │ │\n");
printf(" ╰──────────────────╯\n\n");
printf(" 请输入工号以确认员工唯一\n");
printf(" ");
scanf("%s",temp);
now=first->next;
flagg=0;
while(now!=NULL)
{
if(strcmp(now->person.num,temp)==0)
{
flagg=1;
break;
}
now=now->next;
}
system("cls");
printf("主菜单-->输入员工信息-->查询结果\n\n\n");
if(flagg==0)
{
Prompt(Error_Find);
printf("\n\n员工不存在!是否继续修改?(y/n)");
scanf("%c",&modify);
continue;
}
}
printf(Head1);
printf(Head2);
printf(Head3);
printf(Data);
printf(Head3);
printf(Frame);
printf(StaffD,now->person.name,now->person.num,now->person.salary,now->person.work_hour,now->person.Sum_Salary);
printf(Frame);
printf(Tail);
printf("\n 请输入修改信息 \n");
printf(" 员工姓名:");
scanf("%s",now->person.name);
printf(" 员工工号:");
scanf("%s",now->person.num);
printf(" 员工工资(元/时):");
scanf("%d",&now->person.salary);
printf(" 员工工时(时/日):");
scanf("%d%*c",&now->person.work_hour);
now->person.Sum_Salary=now->person.salary*now->person.work_hour*30;
printf("\n\n修改完成!是否继续修改?(y/n)");
scanf("%c",&modify);
}
}
Save();
}
void Output()//查询模块入口
{
int select;
char output='Y';
while(output=='Y'||output=='y')
{
system("cls");
printf("主菜单-->选择查询方式\n\n\n");
printf(" ╭──────────────────╮\n");
printf(" │ 1.编号查询 │\n");
printf(" │ │\n");
printf(" │ 2.姓名查询 │\n");
printf(" │ │\n");
printf(" │ 3.条件查询 │\n");
printf(" ╰──────────────────╯\n\n");
printf("请输入您的选择<1~3>:");
scanf("%d",&select);
if(select==3)
{
Query_Wider();
}
else
{
Query_Narrow(select);
}
printf("\n\n查询完成!是否继续查询?(y/n)");
scanf("%c",&output);
}
return ;
}
void Sort()//排序模块入口
{
char sort='Y';
int select1,select2;
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
while(sort=='y'||sort=='Y')
{
system("cls");
printf("主菜单-->选择排序方式\n\n\n");
printf(" ╭───────────────────╮\n");
printf(" │ 1.按工资查询 │\n");
printf(" │ │\n");
printf(" │ 2.按工时查询 │\n");
printf(" │ │\n");
printf(" │ 3.按总工资查询 │\n");
printf(" ╰───────────────────╯\n\n");
printf("请输入您的选择<1~3>:");
scanf("%d",&select1);
printf("\n");
printf(" ╭────────────────╮\n");
printf(" │ 1.降序 │\n");
printf(" │ │\n");
printf(" │ 2.升序 │\n");
printf(" ╰────────────────╯\n\n");
printf("请输入您的选择<1/2>:");
scanf("%d",&select2);
Sort_S(select1,select2);
printf("\n\n排序查询完成!是否继续?(y/n)");
scanf("%c",&sort);
}
}
void Count()//分段统计员工数量
{
int number[5000]={0},temp,i;
now=NULL;
previous=NULL;
first=NULL;
count=0;
Open_File();
now=first->next;
while(now!=NULL)
{
temp=now->person.Sum_Salary/200;
number[temp]++;
now=now->next;
}
system("cls");
printf("主菜单-->员工信息统计\n\n\n");
printf(Head1);
printf(Head4);
printf(Head3);
for(i=0;i<5000;i++)
{
if(i==0&&number[0]==0)
{
printf(" ┃ …… ┃\n");
}
if(number[i])
{
printf(" ┃ < %5d ~ %5d >: %d(人) ┃\n",i*200,(i+1)*200-1,number[i]);
if(i<4999&&number[i+1]==0)
{
printf(" ┃ …… ┃\n");
}
}
}
printf(Tail);
Return();
}