功能要求:
① 职工基本信息的录入、增加、删除、修改;
② 按各种条件查询职工信息;
③ 应发工资计算;
④ 其它功能,如工资分布情况统计,代交税金计算,津贴发放,工资晋级等。
要求运用文件储存职工信息进行存储 方便进行增加、修改、删除
代码500行左右
功能要求:
① 职工基本信息的录入、增加、删除、修改;
② 按各种条件查询职工信息;
③ 应发工资计算;
④ 其它功能,如工资分布情况统计,代交税金计算,津贴发放,工资晋级等。
要求运用文件储存职工信息进行存储 方便进行增加、修改、删除
代码500行左右
系统按功能分成以下几个模块:
① 主函数模块main:显示工资管理系统的功能界面,根据用户输入的操作指令调用函数实现各个模块功能;
② 头文件模块stdio.h、conio.h、string.h、windows.h:定义相关结构,定义常量及全局变量,声明所有模块中的函数;
③ 读文件模块:从文件中取出用户以前的记录进行各种操作;
④ 写文件模块:把用户的操作数据写回到文件中保存;
⑤ 录入员工信息模块:把员工的信息录入;
⑥ 输出员工信息模块:显示员工的信息;
⑦ 查询员工信息模块:按照条件查询员工的信息;
⑧ 删除员工信息模块:删除员工的信息;
⑨ 修改员工信息模块:修改员工的信息;计算员工实际工资模块:调用函数计算除去上缴工资后的实际工资;
(1)主程序模块
仅包含main()函数,提供对系统的主要控制。在用户未选择退出程序时,通过case匹配各个菜单项。当用户选中某个操作后,调用各函数完成相应的操作。
相应代码如下:
int main()
{
int choose;
struct employee data[20];
count = readfile(data);//调用读入函数
puts("\n");
puts(" 员工信息管理系统 ");
puts("\n");
//do-while循环实现循环使用该功能
do{
printf("\n");
system("pause");
system("cls");
puts(" 功能选择菜单 ");
puts("\n");
puts(" 1、添加员工信息 ");
puts(" 2、查找员工信息 ");
puts(" 3、修改员工信息 ");
puts(" 4、删除员工信息 ");
puts(" 5、显示所有员工信息 ");
puts(" 6、员工实际工资信息 ");
puts(" 0、退出程序 ");
printf("\n");
printf("请输入你的选择:");
scanf("%d", &choose);
switch (choose)
{
case 1:
get_employee(data);
break;
case 2:
search_employee(data);
break;
case 3:
change_employee(data);
break;
case 4:
delete_number(data);
break;
case 5:
out_employee(data);
break;
case 6:
calculate_employee(data);
break;
case 0:
puts("\n谢谢使用\n"); return 0;
default:
printf("\n输入错误,请重新输入选择:");
scanf("%d", &choose);
break;
}
} while (choose != -1);
return 0;
}
(2)读文件模块
包含readfile函数,如果打开文件成功就开始逐行读取,显示到控制台,返回读取到的个数;
相应代码如下:
int readfile(struct employee S[])
{
FILE *fp;//定义文件指针
struct employee s;
if ((fp = fopen("employee.txt", "r")) == NULL)
{
printf("文件打开失败");
return 0;
}
//如果文件打开成功,那么进行读数据
while (!feof(fp))
{
fscanf(fp, "%d\t", &s.number);
fscanf(fp, "%s\t", &s.name);
fscanf(fp, "%s\t", &s.sex);
fscanf(fp, "%s\t", &s.role);
fscanf(fp, "%d\n", &s.age);
fscanf(fp, "%lf\n", &s.salary);
S[count] = s;
count++;
}
printf("\n有%d个员工信息被读入\n",count);
fclose(fp);
return count;
}
(3)写文件模块
包含writefile函数,如果打开文件成功就开始逐行写入数据,然后关闭文件;
相应代码如下:
void writefile(struct employee S[], int count)
{
FILE *fp;
int i;
if ((fp = fopen("employee.txt", "w")) == NULL)
{
printf("文件打开失败");
return;
}
if (count == 0)
{
printf("没有联系人可读");
}
//写入数据
for (i = 0; i < count; i++)
{
fprintf(fp, "%d\t", S[i].number);
fprintf(fp, "%s\t", S[i].name);
fprintf(fp, "%s\t", S[i].sex);
fprintf(fp, "%s\t", S[i].role);
fprintf(fp, "%d\n", S[i].age);
fprintf(fp, "%lf\n", S[i].salary);
}
//printf("共写入%d个人的数据\n", count);
fclose(fp);
}
(4)录入员工信息模块
包含get_employee函数,先判断是否还可以继续录入员工,可以的话开始录入,最后关闭文件;
相应代码如下:
void get_employee(struct employee S[])
{
FILE *fp;
if ((fp = fopen("employee.txt", "w")) == NULL){
printf("\n文件打开错误!\n");
exit(0);
}
if (count > 50){
printf("员工信息已满!\n");
return;
}
else{
struct employee E;
printf("\n");
printf("请输入员工的编号:");
scanf("%d", &E.number);
printf("请输入员工的姓名:");
scanf("%s",E.name);
printf("请输入员工的性别:");
scanf("%s",E.sex);
printf("请输入员工的职称:");
scanf("%s",E.role);
printf("请输入员工的年龄:");
scanf("%d", &E.age);
printf("请输入员工的工资:");
scanf("%lf", &E.salary);
S[count++] = E;//count后加1
printf("\n员工信息已经添加\n\n");
writefile(S,count);//调用读入函数
}
if (fclose(fp)){
printf("\n文件关闭失败!\n");
exit(0);
}
}
(5)输出员工信息模块
包含out_employee函数,先判断是否有输出的数据,有的话就使用for循环输出,没有则提示没有信息可以输出。
相应代码如下:
void out_employee(struct employee S[])
{
if (count == 0){
printf("当前员工表中没有信息!\n");
return;
}
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
if(count!=0){
for (int i = 0; i < count; i++){
printf("%d\t",S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
printf("\n");
}
}
}
(6)查询员工信息模块
包含search_number_employee函数,可以使用多个方式来查询,其中有编号、姓名、年龄、性别、职称、工资等方式,首先使用for循环遍历存储员工的数组,判断是否存在该员工,存在则输出,不存在则提示没有找到该员工
相应代码如下:
/*以下是查询功能代码实现*/
//按编号查询员工信息
void search_number_employee(struct employee S[])
{
int i;//记录员工存在的位置
int flag=0;//标记员工有没有存在
int j;//记录员工存在的位置
int number;
printf("\n");
printf("请输入要查询员工的编号:");
scanf("%d",&number);
//遍历结构体数组,查找有无该编号的员工 若有flag=1,反之flag=0
for (i = 0; i < count; i++){
if (S[i].number == number){
flag = 1;
break;
}
}
//如果存在该员工,那么输出该员工的信息
if (flag){
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
//由于员工数组中有多个编号一样的员工,所以需要继续寻找,用j来标记员工的位置 然后输出该员工的信息
//第二次寻找的起始位置应该从i+1开始 因为之前的已经找过了
for (j = i + 1; j < count; j++){
if (S[j].number == number){
printf("\n");
printf("%d\t", S[j].number);
printf("%s\t", S[j].name);
printf("%s\t", S[j].sex);
printf("%s\t", S[j].role);
printf("%d\t", S[j].age);
printf("%.2f\t", S[j].salary);
}
}
}
else{
printf("没有找到该编号的员工!\n");
}
printf("\n");
system("pause");
}
//按姓名查询员工信息
void search_name_employee(struct employee S[])
{
int i;//记录员工存在的位置
int flag = 0;//标记员工有没有存在
int j;//记录员工存在的位置
char name[10];
printf("\n");
printf("请输入要查询员工的姓名:");
scanf("%s", &name);
//遍历结构体数组,查找有无该姓名的员工 若有flag=1,反之flag=0
for (i = 0; i < count; i++){
if (strcmp(S[i].name, name) == 0){
flag = 1;
break;
}
}
//如果存在该员工,那么输出该员工的信息
if (flag){
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
//由于员工数组中有多个姓名一样的员工,所以需要继续寻找,用j来标记员工的位置 然后输出该员工的信息
//第二次寻找的起始位置应该从i+1开始 因为之前的已经找过了
for (j = i + 1; j < count; j++){
//字符串与字符串不能直接相等,所以使用strcmp进行比较
if (strcmp(S[i].name, name) == 0){
printf("\n");
printf("%d\t", S[j].number);
printf("%s\t", S[j].name);
printf("%s\t", S[j].sex);
printf("%s\t", S[j].role);
printf("%d\t", S[j].age);
printf("%.2f\t", S[j].salary);
}
}
}
else{
printf("没有找到该姓名的员工!\n");
}
printf("\n");
system("pause");
}
//按性别查询员工信息
void search_sex_employee(struct employee S[])
{
int i;//记录员工存在的位置
int flag = 0;//标记员工有没有存在
int j;//记录员工存在的位置
char sex[5];
printf("\n");
printf("请输入要查询员工的性别:");
scanf("%s", &sex);
//遍历结构体数组,查找有无该性别的员工 若有flag=1,反之flag=0
for (i = 0; i < count; i++){
if (strcmp(S[i].sex, sex) == 0){
flag = 1;
break;
}
}
//如果存在该员工,那么输出该员工的信息
if (flag){
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
//由于员工数组中有多个性别一样的员工,所以需要继续寻找,用j来标记员工的位置 然后输出该员工的信息
//第二次寻找的起始位置应该从i+1开始 因为之前的已经找过了
for (j = i+1; j < count; j++){
if (strcmp(S[i].sex, sex) == 0){
printf("\n");
printf("%d\t", S[j].number);
printf("%s\t", S[j].name);
printf("%s\t", S[j].sex);
printf("%s\t", S[j].role);
printf("%d\t", S[j].age);
printf("%.2f\t", S[j].salary);
}
}
}
else{
printf("没有找到该性别的员工!\n");
}
printf("\n");
system("pause");
}
//按职称查询员工信息
void search_role_employee(struct employee S[])
{
int i;//记录员工存在的位置
int flag = 0;//标记员工有没有存在
int j;//记录员工存在的位置
char role[10];
printf("\n");
printf("请输入要查询员工的职称:");
scanf("%s", &role);
//遍历结构体数组,查找有无该职称的员工 若有flag=1,反之flag=0
for (i = 0; i < count; i++){
if (strcmp(S[i].role, role)==0){
flag = 1;
break;
}
}
//如果存在该员工,那么输出该员工的信息
if (flag){
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
//由于员工数组中有多个职称一样的员工,所以需要继续寻找,用j来标记员工的位置 然后输出该员工的信息
//第二次寻找的起始位置应该从i+1开始 因为之前的已经找过了
for (j = i+1; j < count; j++){
if (strcmp(S[i].role, role) == 0){
printf("\n");
printf("%d\t", S[j].number);
printf("%s\t", S[j].name);
printf("%s\t", S[j].sex);
printf("%s\t", S[j].role);
printf("%d\t", S[j].age);
printf("%.2f\t", S[j].salary);
}
}
}
else{
printf("没有找到该职称的员工!\n");
}
printf("\n");
system("pause");
}
//按年龄查询员工信息
void search_age_employee(struct employee S[])
{
int i;//记录员工存在的位置
int flag = 0;//标记员工有没有存在
int j;//记录员工存在的位置
int age;
printf("\n");
printf("请输入要查询员工的年龄:");
scanf("%d", &age);
//遍历结构体数组,查找有无该年龄的员工 若有flag=1,反之flag=0
for (i = 0; i < count; i++){
if (S[i].age == age){
flag = 1;
break;
}
}
//如果存在该员工,那么输出该员工的信息
if (flag){
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
//由于员工数组中有多个年龄一样的员工,所以需要继续寻找,用j来标记员工的位置 然后输出该员工的信息
//第二次寻找的起始位置应该从i+1开始 因为之前的已经找过了
for (j = i+1; j < count; j++){
if (S[j].age == age){
printf("\n");
printf("%d\t", S[j].number);
printf("%s\t", S[j].name);
printf("%s\t", S[j].sex);
printf("%s\t", S[j].role);
printf("%d\t", S[j].age);
printf("%.2f\t", S[j].salary);
}
}
}
else{
printf("没有找到该年龄的员工!\n");
}
printf("\n");
system("pause");
}
//按工资查询员工信息
void search_salary_employee(struct employee S[])
{
int i;//记录员工存在的位置
int flag = 0;//标记员工有没有存在
int j;//记录员工存在的位置
double salary;
printf("\n");
printf("请输入要查询员工的工资:");
scanf("%lf", &salary);
//遍历结构体数组,查找有无该工资的员工 若有flag=1,反之flag=0
for (i = 0; i < count; i++){
if (S[i].salary == salary){
flag = 1;
break;
}
}
//如果存在该员工,那么输出该员工的信息
if (flag){
printf("编号\t姓名\t性别\t职称\t年龄\t工资\n");
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
//由于员工数组中有多个工资一样的员工,所以需要继续寻找,用j来标记员工的位置 然后输出该员工的信息
//第二次寻找的起始位置应该从i+1开始 因为之前的已经找过了
for (j = i+1; j < count; j++){
if (S[j].salary == salary){
printf("\n");
printf("%d\t", S[j].number);
printf("%s\t", S[j].name);
printf("%s\t", S[j].sex);
printf("%s\t", S[j].role);
printf("%d\t", S[j].age);
printf("%.2f\t", S[j].salary);
}
}
}
else{
printf("没有找到该工资的员工!\n");
}
printf("\n");
system("pause");
}
//查询员工信息
void search_employee(struct employee S[])
{
if (count == 0){
printf("\n当前员工表中没有信息!\n");
return;
}
int choose;//设置选择的类型
do{
system("cls");
puts(" 请选择要查询员工的方式:");
printf("\n");
puts(" 1、按编号查找");
puts(" 2、按姓名查找");
puts(" 3、按性别查找");
puts(" 4、按职称查找");
puts(" 5、按年龄查找");
puts(" 6、按工资查找");
puts(" 0、退出查询");
printf("\n");
printf("请输入你的选择:");
scanf("%d", &choose);
switch (choose)
{
case 1:
search_number_employee(S);
break;
case 2:
search_name_employee(S);
break;
case 3:
search_sex_employee(S);
break;
case 4:
search_role_employee(S);
break;
case 5:
search_age_employee(S);
break;
case 6:
search_salary_employee(S);
break;
case 0:
printf("谢谢使用该功能!\n");
return;
default:
printf("\n输入错误,请重新输入选择:");
scanf("%d", &choose);
break;
}
} while (choose != 0);
}
/* 查询代码完成*/
(7)删除信息模块
包含delete_number函数,通过编号来删除员工的信息,通过判断输入的员工的编号与存储员工数组的编号是否相等,相等则删除,删除完成以后提示删除成功,否则提示删除失败;
相应代码如下:
void delete_number(struct employee S[])
{
printf("\n");
puts(" 当前员工的信息如下:");
printf("\n");
out_employee(S);
printf("\n");
int choose_number;//存储需要删除的员工编号
int flag=0;//标记有没有该员工
int sum_count=0;//用来记录删除了几个员工信息
printf("\n");
printf("请输入要删除员工的编号:");
scanf("%d", &choose_number);
for (int k = 0; k < count; k++){
for (int i = 0; i <= count; i++){
if (S[i].number == choose_number){//找到了需要删除的员工编号
flag = 1;
if (flag){
for (int j = i; j < count; j++){
S[j] = S[j + 1];
}
sum_count++;//删除了一个员工就加一
}
}
}
}
count = count - sum_count;
if (flag == 1){
printf("\n该员工信息已经删除\n");
}
writefile(S, count);
}
(8)修改员工信息模块
包含change_employee函数,可以修改多种员工信息,先用do while循环输出要修改哪一个员工信息,然后进入相应的case模块实现修改操作;
相应代码入下:
void change_employee(struct employee S[])
{
int choose;
do{
system("cls");
printf("\n");
puts(" 当前员工的信息如下:");
printf("\n");
out_employee(S);
printf("\n");
puts(" 请选择需要修改的信息");
printf("\n");
puts(" 1、编号");
puts(" 2、姓名");
puts(" 3、性别");
puts(" 4、职称");
puts(" 5、年龄");
puts(" 6、工资");
puts(" 0、退出");
printf("\n请输入你的选择:");
scanf("%d", &choose);
switch (choose)
{
case 1:
{
char name[10];
int number;
int flag = 0;//标记信息是否被修改
printf("\n请输入需要修改信息的员工的姓名:");
scanf("%s", name);
printf("\n请输入需要修改的员工编号:");
scanf("%d", &number);
for (int i = 0; i < count; i++){
if (strcmp(S[i].name, name) == 0){
if (S[i].number == number){
printf("\n修改前后的信息不能一样!\n");
break;
}
S[i].number = number;
flag = 1;
}
}
if (flag == 0){
printf("\n修改信息失败!\n");
}
else
printf("\n修改信息成功!\n");
writefile(S, count);
system("pause");
break;
}
case 2:
{
char name[10];
int number;
int flag = 0;//标记信息是否被修改
printf("\n请输入需要修改信息的员工的编号:");
scanf("%d", &number);
printf("\n请输入需要修改的员工姓名:");
scanf("%s", name);
for (int i = 0; i < count; i++){
if (S[i].number == number){
if (strcmp(S[i].name, name) == 0){
printf("\n修改前后的信息不能一样!\n");
break;
}
strcpy(S[i].name, name);
flag = 1;
}
}
if (flag == 0){
printf("\n修改信息失败!\n");
}
else
printf("\n修改信息成功!\n");
writefile(S, count);
system("pause");
break;
}
case 3:
{
char sex[5];
int number;
int flag = 0;//标记信息是否被修改
printf("\n请输入需要修改信息的员工的编号:");
scanf("%d", &number);
printf("\n请输入需要修改的员工性别:");
scanf("%s", sex);
for (int i = 0; i < count; i++){
if (S[i].number == number){
if (strcmp(S[i].sex, sex) == 0){
printf("\n修改前后的信息不能一样!\n");
break;
}
strcpy(S[i].sex, sex);
flag = 1;
}
}
if (flag == 0){
printf("\n修改信息失败!\n");
}
else
printf("\n修改信息成功!\n");
system("pause");
writefile(S, count);
break;
}
case 4:
{
char role[10];
int number;
int flag = 0;//标记信息是否被修改
printf("\n请输入需要修改信息的员工的编号:");
scanf("%d",&number);
printf("\n请输入需要修改的员工职称:");
scanf("%s", role);
for (int i = 0; i < count; i++){
if (S[i].number == number){
if (strcmp(S[i].role, role) == 0){
printf("\n修改前后的信息不能一样!\n");
break;
}
strcpy(S[i].role, role);
flag = 1;
}
}
if (flag == 0){
printf("\n修改信息失败!\n");
}
else
printf("\n修改信息成功!\n");
system("pause");
writefile(S, count);
break;
}
case 5:
{
int age;
int number;
int flag = 0;//标记信息是否被修改
printf("\n请输入需要修改信息的员工的编号:");
scanf("%d", &number);
printf("\n请输入需要修改的员工年龄:");
scanf("%d", &age);
for (int i = 0; i < count; i++){
if (S[i].number == number){
if (S[i].age == age){
printf("\n修改前后的信息不能一样!\n");
break;
}
S[i].age = age;
flag = 1;
}
}
if (flag == 0){
printf("\n修改信息失败!\n");
}
else
printf("\n修改信息成功!\n");
writefile(S, count);
system("pause");
break;
}
case 6:
{
double salary;
int number;
int flag = 0;//标记信息是否被修改
printf("\n请输入需要修改信息的员工的编号:");
scanf("%d", &number);
printf("\n请输入需要修改的员工工资:");
scanf("%lf", &salary);
for (int i = 0; i < count; i++){
if (S[i].number == number){
if (S[i].salary == salary){
printf("\n修改前后的信息不能一样!\n");
break;
}
S[i].salary = salary;
flag = 1;
}
}
if (flag == 0){
printf("\n修改信息失败!\n");
}
else
printf("\n修改信息成功!\n");
writefile(S, count);
system("pause");
break;
}
case 0:
printf("\n谢谢使用该功能!\n");
return;
default:
break;
}
}while (choose != 0);
}
(9)计算员工应得工资模块
包含calculate_employee函数,判断员工是否存在,存在就找到他的工资,然后调用函数计算他应上缴的费用,输出他的实际应得工资;
相应代码如下:
void calculate_employee(struct employee S[])
{
FILE *fp;
fp = fopen("employee.txt","w");
if (count == 0){
printf("\n员工信息表中没有信息!\n");
return;
}
else{
puts("原来员工的信息如下:");
out_employee(S);
puts("");
for (int i = 1; i <= count; i++){
S[i].salary = S[i].salary * (1-0.15);
}
writefile(S, count);
puts("计算实际工资之后员工的信息如下:");
out_employee_fact(S);
}
puts("");
}
由于修改之后的员工信息依然需要输出,所以在这里我们小组成员改进了输出函数,附上代码如下:
void out_employee_fact(struct employee S[])
{
if (count == 0){
printf("当前员工表中没有信息!\n");
return;
}
printf("编号\t姓名\t性别\t职称\t年龄\t实际工资\n");
if (count != 0){
for (int i = 0; i < count; i++){
printf("%d\t", S[i].number);
printf("%s\t", S[i].name);
printf("%s\t", S[i].sex);
printf("%s\t", S[i].role);
printf("%d\t", S[i].age);
printf("%.2f\t", S[i].salary);
printf("\n");
}
}