1.课程目的
本程序旨在训练学生的C语言基本编程能力,通过串联C语言输入输出、循环语句、子函数设计、数组、结构体等知识点,完成一个简单系统的设计开发。
2、系统功能
(1) 通过菜单形式实现人机交互界面
(2) 实现录入员工基本信息和工资功能
(3) 实现删除指定员工的基本信息和工资(基本工资和津贴)功能
(4) 实现修改指定员工的基本信息和工资功能
(5) 实现查询指定员工的基本信息和工资功能
(6) 实现对所有员工的工资进行统计功能,包括以下任务:
任务1.对员工的基本工资和津贴进行求和得到实发工资(实发工资=基本工资+津贴)
任务2.对员工的实发工资实现从小到大或从大到小排序。
3、设计思想
(1)人机交互界面
使用printf()和scanf()输入输出函数设计出主界面交互菜单,通过switch case语句判断输入的选项值,执行相对应得子函数。
用户推出菜单选项之后,需要使用C语言文件操作,保存已经录入的全部员工信息和工资。程序下次启动时可以直接查询上次保存的数据。
(2)添加员工信息
设计为单独的子函数供主函数调用。
定义一个结构体类型,包括五个成员变量(编号,姓名,性别,基本工资,津贴,实发工资),并用该类型定义一个全局的结构体数组,供外部录入员工信息时存储。
定义一个全局变量累存储当前员工的个数。
添加员工信息时,需要从外部读入员工的编号,姓名,性别,基本工资和津贴,在获取编号时需要判断是否输入重复,如果编号相同则重新输入,员工数量加一,并根据当前员工个数将其保存在结构体数组对应序号的元素中。
一个员工信息录入结束后可以提示用户输入Y/N来选择是否接着输入下一个员工信息。
(3)显示全部员工的信息
通过对当前结构体数组进行遍历,并显示输出
(4)按实发工资排序
利用选择排序或者冒泡排序法,将当前结构体数组根据元素中实发工资变量,从小到大排序。然后对当排序完成的结构体数组进行遍历显示输出,从而达到按实发工资排序的效果。
(5)查找单个员工
根据输入需要查找员工的编号,遍历当前结构体数组,判断是否含有一致编号的元素,若有则显示输出对应的员工信息,否则显示无此人。
(6)删除单个员工
输入需要删除员工的编号,遍历当前结构体数组,判断是否含有一致编号的元素,若有则从该元素之后依次将下一个元素赋值到上一个元素,直至最后一个赋值完成,最后当前员工个数变量减1。
(7)修改员工信息
输入需要修改学员工的编号,遍历当前结构体数组,判断是否含有一致编号的元素,若有则依次从外部读入用户所修改的值,保存到对应成员变量中。
typedef struct
{
char num[12]; /*员工编号*/
char name[20]; /*姓名*/
char sex[2]; /*性别*/
int salary; /*薪资*/
int allowance; /*津贴*/
int truesalary; /*实发工资*/
}Staff;
Staff staffAll[80]; /*结构体数组*/
int staff_number = 0; /*员工的总人数*/
/*菜单函数*/
int menu_select()
{
int check_number;
do{
system("cls"); /*运行前清屏clear screen,在stdlib.h中bai*/
printf("\t===============员工工资管理系统===============\n"); /*菜单选择*/
printf("\t 1. 添加员工信息 \n");
printf("\t 2. 显示员工信息 \n");
printf("\t 3. 按实发工资排序 \n");
printf("\t 4. 查找单个员工 \n");
printf("\t 5. 删除单个员工 \n");
printf("\t 6. 修改员工信息 \n");
printf("\t 0. 退出 \n");
printf("\t==============================================\n");
printf("请输入选择(0-6):");
scanf("%d",&check_number); /*读入选择*/
}while(check_number<0||check_number>6);
return(check_number); /*返回选择*/
}
//以下的student都是形式参数,真正的数组是在全局变量里定义的staffAll数组
/*输入若干条记录*/
void Input(Staff staff[])
{
int i=0,j;
char flag,clear[10]; /*clear[10]为清除多余的数据所用*/
char staffNum[12]; //暂存某员工编号
//判断是否已经存在相同员工的编号
while(flag!='n'&&flag!='N') //判断flag是不是n/N,以此判断是否继续输入员工信息
{
printf("输入员工编号: ");
scanf("%s",staffNum);
while(strcmp(staff[i].num,staffNum)!=0&&i<staff_number)
{
i++; /*查找判断*/
}
//查找到有相同编号的员工,则无法增加员工信息,返回主函数
if(i<staff_number)
printf("已有相同编号的员工,请重新输入\n");
//如果没有查找到相同编号的员工,即可增加员工信息
else
{
if(i==staff_number)
{
staff[staff_number].truesalary=staff[staff_number].salary+staff[staff_number].allowance;
gets(clear); //*清除多余的输入
printf("该员工信息已录入完毕,是否继续?(Y/N)");
scanf("%c",&flag); //输入判断
staff_number++;//总人数加1
i=0;
}
}
}
}
/*显示所有记录*/
void Display(Staff staff[])
{
int i=0;
printf("编号\t姓名\t性别\t基本工资\t津贴\t实发工资\n");
printf("——————————————————————————————————————\n");
while(i!=staff_number)
{
printf("%s\t%s\t%s\t%d\t\t%d\t%d\n",staff[i].num,staff[i].name,staff[i].sex,staff[i].salary,staff[i].allowance,staff[i].truesalary);
i=i+1;
}
}
/*按实发工资排序*/
void Sort_by_sum(Staff staff[])
{
Staff staff_truesalary;
int i,j;
for(i=0;i<staff_number-1;i++)
{
for(j=0;j<staff_number-1;j++)
{
if(staff[j].truesalary>staff[j+1].truesalary)
{
staff_truesalary=staff[j];
staff[j]=staff[j+1];
staff[j+1]=staff_truesalary;
}
}
}
}
/*按编号查找并显示一个记录*/
void Query_a_record(Staff staff[])
{
int i,j;
char findnum[20]; //输入员工的编号
printf("请输入要查找的员工的编号: "); //输入员工的编号
scanf("%s",findnum);
for(j=0;j<staff_number;j++)
{
if(strcmp(staff[j].num,findnum)==0)
{
i=j;
} /*查找判断*/
}
printf("编号\t姓名\t性别\t基本工资\t津贴\t实发工资\n");
printf("———————————————————————————————————————\n");
printf("%s\t%s\t%s\t%d\t\t%d\t%d\n",staff[i].num,staff[i].name,staff[i].sex,staff[i].salary,staff[i].allowance,staff[i].truesalary);
}
/*按编号查找,删除一条记录*/
void Delete_a_record(Staff staff[])
{
int i,j;
char findnum[20];
printf("请输入将要删除的员工编号: "); //输入员工的编号
scanf("%s",findnum);
for(j=0;j<staff_number;j++)
{
if(strcmp(staff[j].num,findnum)==0)
{
i=j;
}
} /*查找判断*/
for(;i<staff_number-1;i++)
{
staff[i]=staff[i+1];
}
staff_number--;
printf("该员工信息已删除!\n") ;
}
/*修改员工信息*/
void modifyStudentinformation(Staff staff[])
{
char changenum[20];
int i=0;
printf("输入将要修改的员工编号: ");
scanf("%s",changenum);
while(strcmp(staff[i].num,changenum)!=0&&i<staff_number)
{
i++; /*查找判断*/
}
}
/*从文件中读入数据*/
void AddfromText(Staff staff[])
{
int i=0;
int number = 0;
FILE *fp; /*定义文件指针*/
if((fp=fopen("E:\\staff.txt","rb"))==NULL) /*打开二进制文件,如果不存在则创建*/
{
fp=fopen("C:\\staff.txt","wb");
}
fscanf(fp,"共有%d条记录\n",&staff_number); /*读入总记录量*/
while(i<staff_number) /*循环读入数据*/
{
fscanf(fp,"%s %s %s %d %d %d\n",staff[i].num,staff[i].name,staff[i].sex,&staff[i].salary,&staff[i].allowance,&staff[i].truesalary);
i++;
}
fclose(fp);
}
/*将所有记录写入文件*/
void WritetoText(Staff staff[])
{
int i=0;
FILE *fp;
fp=fopen("E:\\staff.txt","wb");
printf("共有%d条记录\n",staff_number);
fprintf(fp,"共有%d条记录\n",staff_number);
while(i<staff_number)
{
fprintf(fp,"%s %s %s %d %d %d\n",staff[i].num,staff[i].name,staff[i].sex,staff[i].salary,staff[i].allowance,staff[i].truesalary);
i++;
}
fclose(fp);
}
/*主函数*/
int main()
{
AddfromText(staffAll);
for(;;)
{
switch(menu_select()) /*选择判断*/
{
case 1:
printf("请添加员工信息\n"); /*输入若干条记录*/
Input(staffAll);
break;
case 2:
printf("显示所有员工记录\n"); /*显示所有记录*/
Display(staffAll);
system("pause");
break;
case 3:
printf("按实发工资排序\n");
Sort_by_sum(staffAll); /*按实发工资排序*/
Display(staffAll);
printf("按实发工资排序成功!\n");
system("pause");
break;
case 4:
printf("查找单个员工\n");
Query_a_record(staffAll); /*按姓名查找员工*/
system("pause");
break;
case 5:
printf("删除指定员工\n");
Delete_a_record(staffAll); /*按姓名查找,删除一条记录*/
system("pause");
break;
case 6:
printf("修改员工信息\n");
modifyStudentinformation(staffAll); /*修改员工信息*/
system("pause");
break;
case 0:
WritetoText(staffAll);
printf("已保存,退出系统\n"); /*结束程序*/
system("pause");
exit(0);
}
}
}