内蒙古工业大学信息工程学院
实 验 报 告
课程名称: c语言
实验名称:
实验类型: 验证性□ 综合性√ 设计性□
实验室名称: 电西8楼
班级: 计12-2 学号:201220201042
姓名: 孙亚赛 组别:
同组人: 勾涛 付启恒 成绩:
实验日期: 20##-3-3
目录
1 题目与要求............................................................................................................ 3
2 功能设计............................................................................................................... 5
2.1算法设计....................................................................................................... 5
2.2 模块流程图.................................................................................................. 7
3 程序代码设计........................................................................................................ 8
4 C程序设计总结.................................................................................................... 22
5 结束语................................................................................................................. 23
6 源程序............................................................................................................... 23
1 题目与要求
程序设计的目的和要求
1.目的:
1)复习、巩固程序设计的基础知识,进一步加深对程序设计语言的理解和掌握;熟练使用函数、结构体、文件、数组、循环与选择、链表和指针等知识点,熟练应用C语言综合知识。
2)为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力。提高学生适应实际,实践编程的能力;
3)培养学生在项目开发中团队合作精神、创新意识及能力。
2.要求:
1)对系统进行功能模块分析、控制模块分析正确,符合题目要求,实现相应功能;可以加以其他功能或修饰,使程序更加完善、合理;
2)系统设计要实用、编程简练、功能全面、界面美观、操作使用便捷、程序运行稳定;
3)说明书、流程图要清晰;
4)记录设计情况(备查,也为编写设计说明书作好准备);
5)要求采用模块化程序设计方法,及锯齿型书写格式,要求上机调试通过,能正确运行;
6)设计上交内容:设计报告一份(按格式书写);源程序一份(电子版,能编译成可执行文件并能正常运行。每个班由班长负责收集并上交)。
题目:职工工资管理系统
1)、应提供一个界面来调用各个功能,调用界面和各个功能的操作界面应尽可能清晰美观。
2)、输入功能:职工信息的录入(包括从文件中导入职工信息数据),可以一次完成若干条记录的输入。
3)、浏览功能:完成对全部职工信息的显示。
4)、查找功能:
①完成按姓名查询职工的相关信息,并显示。
②完成按ID号查询职工的相关信息,并显示。
5)、删除功能:通过输入ID号完成对职工的信息进行删除。
6)、添加功能:完成添加新职工的信息。
7)、修改功能:通过输入ID号完成对职工的信息进行修改。
8)、计算功能:计算职工的各项工资,并得出实发工资。[个人收入所得税按现行税率计算]
9)、统计功能:统计并输出符合指定条件的职工人数及其占总人数和百分比。[如实发工资在5000元以上。
10)、保存功能:可以将职工信息数据保存至指定的文件中。
11)、退出职工工资管理系统。
职工信息应至少包括以下数据:ID号、姓名、基础工资、职务工资、住房公积金、个人收入所得税,水电费、实发工资。
1.1:我实现的题目中的问题:
主菜单页面制作;
职工数据输入;
职工全部数据浏览;
按姓名、学号查找职工数据;
通过ID号对职工数据进行删除;
通过ID号对职工数据修改;
职工数据统计(将自己题目做完后完成了其它功能)。
1.2本系统涉及的知识点:结构体、数组、循环、选择、函数调用、分支、指针、全局变量、文件读取、保存
1.3我实现的题目功能:
主菜单页面制作;
职工数据输入;
职工全部数据浏览;
按姓名、学号查找职工数据;
通过ID号对职工数据进行删除;
通过ID号对职工数据修改;
职工数据统计;
2 功能设计
2.1算法设计
2.1.1进入主函数后执行newu函数,利用switch语句设计如图1所示的主菜单
请输入要执行的功能对应选项(1-10)
1.录入职工信息
2.浏览职工信息
3.添加职工信息
4.查询职工信息
5.删除职工信息
6.修改职工信息
7.员工实发工资
8.职工工资排序
9.职工工资统计
10.返回菜单
2.1.2选择1后录入职工信息,执行input函数利用循环录入职工各项信息,输入完毕后将所有数据存入文件。
2.1.3输入2后浏览职工信息,执行view函数,读取文件,利用循环将职工各项信息显示
2.1.4输入3后添加职工信息,执行tianjia函数,读取文件,输入添加人数,然后调用input1函数,利用全局变量D自动将新添加的职工信息补充到已存职工信息后面(利用循环),保存至文件
2.1.5输入4后查找职工信息(利用switch语句,通过ID号和姓名查找),利用charge函数,读取存入到文件中的职工信息,选取相应的使用通过ID号(charge1函数)和姓名查找(charge2)的函数对职工信息查找
2.1.6输入5后通过ID号删除职工信息,调用delete函数,读取文件,利用循环将与输入ID号相同的文件中的职工信息删除。
2.1.7输入6后通过输入ID号修改员工信息,调用xiugai函数,读取文件通过循环将所需各项信息修改
2.1.8输入7后统计员工工资,调取gongzhi函数,将员工实发工资输出,其中实发工资在输入函数input函数中利用选择和循环计算得出
2.1.9输入8后进行职工工资函数,调取tongji函数,读取文件,利用循环将职工工资比较,进行排序
2.1.10输入9后进行职工工资统计,调取tongji函数,将职工工资分为5000以上、3000-4000、20##-3000、2000以下四个档次,其中对数据的统计在输入函数input函数中实现。
2.1.11输入10为返回函数,即调用newu函数返回主菜单
2.1.12输入11为写入对使用此系统的意见:
2.2 模块流程图
3 程序代码设计
struct Worker
{
int num; //ID号码
char name[20]; //姓名
int salary1; //基础工资
int salary2; //职务工资
int salary3; //住房公积金
int salary4; //社保金
float salary5;
}stu[10000]; //定义一个足够大的结构体数组
函数功能说明:结构体数组,用来存放题目所需信息,定义10000个结构体是为了构建足够大的结构体使所有数据正常存取。
void input(int n)----------------------------输入函数
{
void save(int n); //声明一个保存函数
void newu(); //声明一个菜单函数
int i=0;
for (i=0;i<n;i++)
{
printf ("\n请输入职工号:");
scanf ("%d",&stu[i].num );
printf ("\n请输入姓名:");
scanf ("%s",&stu[i].name);
printf ("\n请输入基础工资:");
scanf ("%d",&stu[i].salary1);
printf ("\n请输入职务工资:");
scanf ("%d",&stu[i].salary2 );
printf ("\n请输入住房公积金:");
scanf ("%d",&stu[i].salary3 );
printf ("\n请输入社保金额:");
scanf ("%d",&stu[i].salary4 );
if(stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 > 3500)
{
int a;
float b;
a = stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 - 3500;
if (a>1500&&a<4500)
{
b = (float)(a * 0.1 - 105);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
if (a>9000&&(a<4500||a==4500))
{
b = (float)(a * 0.1 - 555);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
}
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 ;
}
save(n); //对结构体数据进行储存
newu(); //返回菜单
}
函数功能说明:将职工信息存入文件,save函数是保存函数,将录入的信息(职工的姓名、编号、基础工资、职务工资、住房公积金、社保金额)存入指定文件中,newu函数是主菜单函数,执行完输入函数后转入主菜单进行其他功能的进行。此函数中通过for循环将多个职工信息录入。下面的if语句是用来统计职工工资的,在此函数录入职工信息的同时将其信息统计。
void tianjia()----------------------------------------------添加函数
{
void input1(int n);
int i;
printf ("←请输入添加的人数→;");
scanf ("%d",&i);
input1(i);
}
函数功能说明:此函数为添加函数,通过此函数输入要添加的人数,再转入input1函数,添加职工信息。
void input1(int n)--------------------------添加函数
{
void save(int n);
void newu();
int i=0;
for (i=D;i<n+D;i++)
{
printf ("\n请输入职工号:");
scanf ("%d",&stu[i].num );
printf ("\n请输入姓名:");
scanf ("%s",&stu[i].name);
printf ("\n请输入基础工资:");
scanf ("%d",&stu[i].salary1);
printf ("\n请输入职务工资:");
scanf ("%d",&stu[i].salary2 );
printf ("\n请输入住房公积金:");
scanf ("%d",&stu[i].salary3 );
printf ("\n请输入员工社保金额:");
scanf ("%d",&stu[i].salary4 );
if(stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 > 3500)
{
int a;
float b;
a = stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 - 3500;
if (a>1500&&a<4500)
{
b = (float)(a * 0.1 - 105);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
if (a>9000&&(a<4500||a==4500))
{
b = (float)(a * 0.1 - 555);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
}
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 ;
}
save(n);
newu();
}
函数功能说明:此函数为添加函数,在原有职工信息的基础上再添加新的职工信息,定义一个全局变量D是原先输入的职工个数,此添加函数直接从D项开始录入新的职工信息,If下面的语句是实发工资的计算,在录入职工信息的过程中将实发工资计算出来,实发工资的函数见下面的函数。
void save(int n)-----------------------保存函数(将结构体的数据储存到文件中)
{
FILE *fp,*fp1; //
int i;
if ((fp=fopen("abc.dat","wb"))==NULL)
{
printf ("cannot open file\n");
return ;
}
for (i=0;i<n+D;i++)
if (fwrite(&stu[i],sizeof(struct Worker),1,fp)!=1)
printf ("file write error\n");
D = i;
if ((fp1=fopen("abcd.dat","wb"))==NULL)
{
printf ("cannot open file\n");
return ;
}
fwrite(&D,2,1,fp1);//记录结构体数组的个数并经其储存到文件中
fclose(fp);
fclose(fp1);
}
函数功能说明:此函数为保存函数,将输入或修改后的职工信息存入文件,在其中定义两个指针,各指向一个文件,一个文件存各职工信息,一个文件存职工个数,函数内容为文件读取的固定格式。
void view(int n)----------------------------------------------浏览函数
{
int i;
FILE *fp,*fp1; //定义两个指针文件
if ((fp=fopen("abc.dat","rb"))==NULL) //以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL) //以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1); //读出文件中的D的值
printf ("\nID号码 姓名 基础工作 职务工资 住房公积金 社保金 实发工资\n");
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
printf ("%5d %6s %5d %4d %6d %5d %5.2f\n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3,stu[i].salary4,stu[i].salary5 );
}
fclose(fp);
fclose(fp1);
newu();
}
函数功能说明:此函数为浏览函数,先打开文件读取数据,再通过循环将文件中结构体中的数据依次输出。
void newu()----------------------------------------------------菜单函数(界面函数)
{
void tianjia(); //函数声明
void delet(); //函数声明
void charge(); //函数声明
void paixu(); //函数声明
void xiugai(); //函数声明
void tongji(); //函数声明
void gongzhi(); //函数声明
int i,n; //菜单(界面)
printf ("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆欢迎登入职工管理系统☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf (" <1>录入职工信息 <2>浏览职工信息 \n");
printf (" <3>添加员工信息 <4>查询员工信息 \n");
printf (" <5>删除员工信息 <6>员工信息修改 \n");
printf (" <7>员工实发工资 <8>员工工资排序 \n");
printf (" <9>员工工资统计 <10>返回菜单 \n");
printf (" <9>意见反馈 \n");
printf ("\n☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf ("★请您在(1-7)中选择一个数字进行相应的操作★:");
scanf ("%d",&n);
if (n==1)
{
printf ("★请确定您本次将要录入职工的数目★:");
scanf ("%d",&i);
}
switch (n)
{
case 1: input(i); break;
case 2: view(D); break;
case 3: tianjia();break;
case 4: charge(); break;
case 5: delet(); break;
case 6: xiugai(); break;
case 7: gongzhi();break;
case 8: paixu(); break;
case 9: tongji(); break;
case 10: newu(); break;
case 11: yijian();break;
}
}
函数功能说明:此函数为主菜单页面,通过此菜单运用switch函数可以实现系统11个功能的调用,通过对老师上传的例系统分析,我设计了此想主菜单页面。
void delet()----------------------------------------------------删除函数
{
int num,i,n,m;
FILE *fp,*fp1;
if ((fp=fopen("abc.dat","wb"))==NULL) //以写的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","wb"))==NULL)//以写的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,sizeof(int),1,fp1);
printf ("*请输入您想删除的员工ID号*:"); //找到要删除员工的ID号码
scanf ("%d",&num);
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (stu[i].num==num&&i<D)
{
n = i;
fread(&stu[i+1],sizeof(struct Worker),1,fp);
stu[n] = stu[i+1]; //将后一个人的数据赋予前一个人,从而实现对员工信息的有效删除
i++;
n++;
}
}
for (i=0;i<D-1;i++)
{
fwrite(&stu[i],sizeof(struct Worker),1,fp); // 删除一个人的数据后D就要减一
}
D = D - 1;
fwrite(&D,sizeof(int),1,fp1);
fclose(fp);
fclose(fp1);
printf("是否继续删除员工信息 1继续? 2返回菜单");
scanf("%d",&m);
if (m==1)
delet();
newu();
}
函数功能说明:此函数为删除函数,主要原理是通过循环将所输入编号的职工的信息替换为其编号的下一个职工的信息将输入编号的职工的信息删除。
void charge()------------------------------------------------查找函数
{
int num;
printf ("按姓名查找请按1 按ID号查找请按2:");
scanf ("%d",&num);
switch (num)
{
case 1: charge1(); break;
case 2: charge2(); break;
}
}
函数功能说明:此函数为查找函数的主菜单,此函数使用switch语句可以调取charge1(按姓名查找)、charge2(按ID号查找)两个查找方式。
void charge1()-----------------------------------------------------------查找函数
{
FILE *fp,*fp1; //利用ID号进行查找信息
int i;
char name[20];
printf ("请输入您要查询的员工姓名:");
scanf ("%s",name);
if ((fp=fopen("abc.dat","rb"))==NULL) //打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
for (i=0;i<D;i++) //利用循环的方法找到信息
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (strcmp(stu[i].name ,name)==0)
{
printf ("%-5d %-6s %d %d %d \n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3 );
break;
}
}
fclose(fp);
fclose(fp1);
newu();
}
函数工呢说明:此函数为使用姓名查找方式将某位职工的信息查找,使用strcmp函数将存入文件的职工姓名与输入的姓名比较,将指定的文件中某个职工信息查找出来。
void charge2()-------------------------------------------------------------利用ID号进行查找信息
{
FILE *fp,*fp1;
int num,i;
printf ("请输入您要查询的员工ID号码:");
scanf ("%d",&num);
if ((fp=fopen("abc.dat","rb"))==NULL) //打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
for (i=0;i<D;i++) //利用循环的方法找到信息
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (stu[i].num == num)
{
printf ("%-5d %-6s %d %d %d \n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3 );
break;
}
}
newu();
fclose (fp);
fclose (fp1);
}
函数功能说明:此函数为利用ID号查找职工信息,原理与使用姓名查找特定职工信息相似,使用for循环将文件中与输入特定ID号相同的职工信息查找到并且输出。
void paixu()--------------------------------------------------------------------排序函数
{
FILE *fp,*fp1;
int n,i,j,k;
struct Worker temp;
if ((fp=fopen("abc.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
for (n=0;n<D;n++) //利用冒泡法排序
{
fread(&stu[n],sizeof(struct Worker),1,fp);
}
for (i=0;i<D-1;i++)
{
k = i;
for (j=i+1;j<D;j++)
{
if (stu[j].salary5 > stu[k].salary5 )
k = j;
}
temp=stu[k];stu[k]=stu[i];stu[i]=temp;
}
printf ("\n\nID号码 姓名 基础工作 职务工资 住房公积金 社保金 实发工资\n");
for (i=0;i<D;i++)
{
printf ("%5d %6s %5d %4d %6d %5d %5.2f\n\n\n\n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3,stu[i].salary4,stu[i].salary5 );
}
fclose(fp);
fclose(fp1);
newu();
}
函数功能说明:此函数为排序函数,利用职工工资排序,使用的原理是冒泡法(for语句嵌套)。
void xiugai()---------------------------------------------------------------------修改函数
{
FILE *fp,*fp1; //fp1统计一共有fp多少组数据,fp中用来存储机体数据;
int num,i,a,b;
if ((fp=fopen("abc.dat","wb"))==NULL)//以写的方式打开文件(即对文件进行初始化)
{
printf ("cannot open file\n");//以读的方式打开文件
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,sizeof(int),1,fp1); //读出fp1中的D即是fp中的数据个数
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
}
printf ("请输入您想修改员工的ID号码:");
scanf ("%d",&num);
for (i=0;i<D;i++)
{
if (stu[i].num==num) //开始修改信息
{
printf ("ID号码是否修改(1为修改n为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("ID号码改为:");
scanf ("%d",&stu[i].num );
}
printf ("姓名是否修改(1为修改n为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("姓名改为:");
scanf ("%s",stu[i].name );
}
printf ("基础工资是否修改(1为修改2为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("基础工资改为:");
scanf ("%d",&stu[i].salary1 );
}
printf ("职务工资是否修改(1为修改2为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("职务工资改为:");
scanf ("%d",&stu[i].salary2 );
}
printf ("住房公积金是否修改(1为修改2为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("住房公积金改为:");
scanf ("%d",&stu[i].salary3 );
}
if(stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 > 3500)
{
int a;
float b;
a = stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 - 3500;
if (a>1500&&a<4500)
{
b = (float)(a * 0.1 - 105);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
if (a>9000&&(a<4500||a==4500))
{
b = (float)(a * 0.1 - 555);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
}
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 ;
}
}
for(i=0;i<D;i++)
{
fwrite(&stu[i],sizeof(struct Worker),1,fp); //开始对文件进行写入数据
}
fclose(fp); //关闭文件
fclose(fp1);
printf ("是否继续修改员工信息 1继续修改 2返回菜单");
scanf ("%d",&b);
if (b==1)
xiugai();
newu();
}
函数功能说明:此函数为修改函数,通过for循环将与所输入的ID号相同的文件中的特定职工信息修改,特定职工的每一项信息修改前都要进行询问选择,将职工的最详尽信息修改完毕。
void tongji()-----------------------------------------------------------------统计函数
{
FILE *fp,*fp1;
int i,n=0,m=0,o=0,p=0;//统计个数
struct Worker temp;
if ((fp=fopen("abc.dat","rb"))==NULL)//以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
printf ("\n员工信息统计如下:\n\n");
for (i=0;i<D;i++)
{
if(stu[i].salary5 > 5000) //计算工资在5000元以上的人数
{
n = n + 1;
}
else if(((stu[i].salary5==5000 )||stu[i].salary5<5000)&&stu[i].salary5 > 4000)//计算工资在4000——5000元之间的人数
{
m = m + 1;
}
else if(((stu[i].salary5==4000 )||stu[i].salary5<4000)&&stu[i].salary5 > 3000)//计算工资在3000——4000元之间的人数
{
o = o + 1;
}
else
p = p + 1; //计算工资在3000元以下的人数
}
printf ("实发工资在 5000元以上的人数为%d占总人数的百分%5.2f\n",n,(float)(100*n/D));
printf ("实发工资在3000到4000之间的人数为%d占总人数的百分%5.2f\n",m,(float)(100*m/D));
printf ("实发工资在2000到3000之间的人数为%d占总人数的百分%5.2f\n",0,(float)(100*o/D));
printf ("实发工资在 2000元以下的人数为%d占总人数的百分%5.2f\n\n\n\n",p,(float)(100*p/D));
newu();
}
函数功能说明:此函数为统计函数,分类标准分为四类,5000元以上,3000-4000元之间,20##-3000元之间,2000元以下,salary【5】的计算在input函数中实现。
void gongzhi()------------------------------------------------------------------------实发工资输出的函数
{
int i;
FILE *fp,*fp1;
if ((fp=fopen("abc.dat","rb"))==NULL) // 以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
printf ("ID号码 姓名 实发工资\n");
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (stu[i].num != 0)
printf ("%5d %s %5.2f\n",stu[i].num ,stu[i].name ,stu[i].salary5 );
}
printf ("\n");
fclose(fp);
fclose(fp1);
newu();
}
函数功能说明:此函数为职工实发工资输出的函数,利用for循环将input函数中求出的实发工资salary5将每位职工的编号、姓名、实发工资输出。
void yijian()------------------------------------------------------------输入意见函数
{
char a[];
printf(“enter your suggestions:\n”);
puts(a);
return 0;
}
函数功能说明:此函数为输入使用此意见的函数,为此系统的创新部分,较为简单。
int main()---------------------------------------------------------------------------主函数
{
void input (int i);
void view(int n);
newu();
return 0;
}
函数功能说明:菜单函数,在菜单函数中通过switch语句通过不同的数字进行相应的操作,以调用不同的函数
4 C程序设计总结
本次试验有六个课题项目可供选择,虽然各个课题内同要求大致相同,但第六个课题功能更全些,内容更加详尽,所以我们决定挑战些高难度的,虽然做起来困那些,但做此课题更能锻炼、提升我们的能力,经过短暂讨论后我们一致同意选最后一个课题。
当老师宣布我们五天的任务是做一个大程序,组员自己商定的视乎,我立刻想到了身边的勾涛,付启恒。平时上课休息我们三个都是形影不离的,另外,勾涛C语言掌握较扎实,有他带着我们任务号完成些。
人员和课题项目选择好以后我们就开始了实验设计,在此过程中组内出现了分歧,勾涛基础好些,想使用链表的方法设计程序,我们的基础较弱,想使用数组的方法。经过讨论,我们最后决定由勾涛先使用链表对课题进行程序设计,我两基础较差,先将课本基础知识过一遍,如果勾涛用链表方法进行得顺利我们就都用链表方法。
第一天的时间里,我看完了从开始到函数的部分,将一个假期遗忘的知识重新拾了起来。将冒泡法等基本且重要的方法掌握了。勾涛那边的情况不甚顺利,在使用链表编译的过程中他遇到很多问题。如果继续下去会浪费很多时间且无法预知程序能否顺利做成。于是他也放弃使用链表。决定用数组相关知识完成题目设计。
第二天我进行的很缓慢,因为指针、结构体、文件属于胶南内容。将知识回忆起来花了很长时间。另外,有些程序较难理解,虽然话了时间但效果依然不甚满意。最后我硬着头皮将这几节知识过了一遍,时间紧迫么。如果在课本上再浪费太多时间就没时间编译题目了。勾涛第二天进行的很顺利。转变思路后,他可谓轻车熟路,将知识运用得很灵活,对课题的构思很快就出来了第二天的编译中,他已经完成了好几个功能。付启恒也在扎实地进行着自己的复习巩固。课题设计进行到现在,我们又进行了讨论,做了对未来对课题的计划。使用数组的方法后勾涛如鱼得水,很快可将此实验课题的编译工作完成。于是我们决定以勾涛的程序为模板,以后的修改工作都在他的代码上进行。我两将复习课本的工作完成后挑选适合自己的功能模块进行编译。
第三天我开始正式对课题编译。首先是简历一个结构体数组,用来存放本体设计到的数据。题目要求的数据有很多歌。考虑到输入数据时的简练便捷,我只选取了职工的ID号码、姓名、基础工资、住房公积金、社保金、实发工资六个数据。考虑到程序的清晰可读性,我决定使用多个调用函数完成各功能的实现。
对于输入的职工人数我用全局变量D定义,以便在各个函数调用方便。对于分配我的任务较简单,很快就完成任务,然后又尝试了其它功能的编译。
收获:巩固了基础知识,对指针、结构体、文件等较难内容有了更深的理解,提高了解决问题的能力、沟通交流的能力和团队合作的能力。尤其是对大程序的分析理解能力有了很大提高。
5编程中遇到的困难及解决方法
在编写程序的过程中就是对文件的保存存在较大的问题,如在修改员工信息后或删除员工信息后不能有效地保存结构体数组信息。有时候修改员工信息后或删除员工信息后直接浏览还是很成功的,但关闭程序后再次运行就不能浏览文件中的数据。考虑到可能是文件没有得到保存,于是我找到abc.dat和abcd.dat文件发现他们都是0字节,断定是在改变员工信息后没有得到保存。于是找到修改函数和删除函数始终没发现原因,在多方努力下终于发现是打开文件的方式不对,我用的是读的方式打开的,这就造成不能修改员工信息,应该利用写的方式打开文件,这样才能保存新的文件信息。
6 结束语
对本次课题设计中勾涛同学、老师给予的帮助表示深切感谢!
7 源程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int D=0;
struct Worker
{
int num; //ID号码
char name[20]; //姓名
int salary1; //基础工资
int salary2; //职务工资
int salary3; //住房公积金
int salary4; //社保金
float salary5;
}stu[10000]; //定义一个足够大的结构体数组
void input(int n)
{
void save(int n); //声明一个保存函数
void newu(); //声明一个菜单函数
int i=0;
for (i=0;i<n;i++)
{
printf ("\n请输入职工号:");
scanf ("%d",&stu[i].num );
printf ("\n请输入姓名:");
scanf ("%s",&stu[i].name);
printf ("\n请输入基础工资:");
scanf ("%d",&stu[i].salary1);
printf ("\n请输入职务工资:");
scanf ("%d",&stu[i].salary2 );
printf ("\n请输入住房公积金:");
scanf ("%d",&stu[i].salary3 );
printf ("\n请输入社保金额:");
scanf ("%d",&stu[i].salary4 );
if(stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 > 3500)
{
int a;
float b;
a = stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 - 3500;
if (a>1500&&a<4500)
{
b = (float)(a * 0.1 - 105);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
if (a>9000&&(a<4500||a==4500))
{
b = (float)(a * 0.1 - 555);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
}
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 ;
}
save(n); //对结构体数据进行储存
newu(); //返回菜单
}
void input1(int n)
{
void save(int n);
void newu();
int i=0;
for (i=D;i<n+D;i++)
{
printf ("\n请输入职工号:");
scanf ("%d",&stu[i].num );
printf ("\n请输入姓名:");
scanf ("%s",&stu[i].name);
printf ("\n请输入基础工资:");
scanf ("%d",&stu[i].salary1);
printf ("\n请输入职务工资:");
scanf ("%d",&stu[i].salary2 );
printf ("\n请输入住房公积金:");
scanf ("%d",&stu[i].salary3 );
printf ("\n请输入员工社保金额:");
scanf ("%d",&stu[i].salary4 );
if(stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 > 3500)
{
int a;
float b;
a = stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 - 3500;
if (a>1500&&a<4500)
{
b = (float)(a * 0.1 - 105);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
if (a>9000&&(a<4500||a==4500))
{
b = (float)(a * 0.1 - 555);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
}
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 ;
}
save(n);
newu();
}
void save(int n) //保存函数(将结构体的数据储存到文件中)
{
FILE *fp,*fp1; //
int i;
if ((fp=fopen("abc.dat","wb"))==NULL)
{
printf ("cannot open file\n");
return ;
}
for (i=0;i<n+D;i++)
if (fwrite(&stu[i],sizeof(struct Worker),1,fp)!=1)
printf ("file write error\n");
D = i;
if ((fp1=fopen("abcd.dat","wb"))==NULL)
{
printf ("cannot open file\n");
return ;
}
fwrite(&D,2,1,fp1);//记录结构体数组的个数并经其储存到文件中
fclose(fp);
fclose(fp1);
}
void view(int n) //浏览函数
{
int i;
FILE *fp,*fp1; //定义两个指针文件
if ((fp=fopen("abc.dat","rb"))==NULL) //以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL) //以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1); //读出文件中的D的值
printf ("\nID号码 姓名 基础工作 职务工资 住房公积金 社保金 实发工资\n");
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
printf ("%5d %6s %5d %4d %6d %5d %5.2f\n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3,stu[i].salary4,stu[i].salary5 );
}
fclose(fp);
fclose(fp1);
newu();
}
void newu() //菜单函数(界面函数)
{
void tianjia(); //函数声明
void delet(); //函数声明
void charge(); //函数声明
void paixu(); //函数声明
void xiugai(); //函数声明
void tongji(); //函数声明
void gongzhi(); //函数声明
int i,n; //菜单(界面)
printf ("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆欢迎登入职工管理系统☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf (" <1>录入职工信息 <2>浏览职工信息 \n");
printf (" <3>添加员工信息 <4>查询员工信息 \n");
printf (" <5>删除员工信息 <6>员工信息修改 \n");
printf (" <7>员工实发工资 <8>员工工资排序 \n");
printf (" <9>员工工资统计 <10>返回菜单 \n");
printf ("\n☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
printf ("★请您在(1-7)中选择一个数字进行相应的操作★:");
scanf ("%d",&n);
if (n==1)
{
printf ("★请确定您本次将要录入职工的数目★:");
scanf ("%d",&i);
}
switch (n)
{
case 1: input(i); break;
case 2: view(D); break;
case 3: tianjia();break;
case 4: charge(); break;
case 5: delet(); break;
case 6: xiugai(); break;
case 7: gongzhi();break;
case 8: paixu(); break;
case 9: tongji(); break;
case 10: newu(); break;
}
}
void tianjia()
{
void input1(int n);
int i;
printf ("←请输入添加的人数→;");
scanf ("%d",&i);
input1(i);
}
void delet() //删除函数
{
int num,i,n,m;
FILE *fp,*fp1;
if ((fp=fopen("abc.dat","wb"))==NULL) //以写的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","wb"))==NULL)//以写的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,sizeof(int),1,fp1);
printf ("*请输入您想删除的员工ID号*:"); //找到要删除员工的ID号码
scanf ("%d",&num);
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (stu[i].num==num&&i<D)
{
n = i;
fread(&stu[i+1],sizeof(struct Worker),1,fp);
stu[n] = stu[i+1]; //将后一个人的数据赋予前一个人,从而实现对员工信息的有效删除
i++;
n++;
}
}
for (i=0;i<D-1;i++)
{
fwrite(&stu[i],sizeof(struct Worker),1,fp); // 删除一个人的数据后D就要减一
}
D = D - 1;
fwrite(&D,sizeof(int),1,fp1);
fclose(fp);
fclose(fp1);
printf("是否继续删除员工信息 1继续? 2返回菜单");
scanf("%d",&m);
if (m==1)
delet();
newu();
}
void charge1() //查找函数
{
FILE *fp,*fp1; //利用ID号进行查找信息
int i;
char name[20];
printf ("请输入您要查询的员工姓名:");
scanf ("%s",name);
if ((fp=fopen("abc.dat","rb"))==NULL) //打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
for (i=0;i<D;i++) //利用循环的方法找到信息
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (strcmp(stu[i].name ,name)==0)
{
printf ("%-5d %-6s %d %d %d \n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3 );
break;
}
}
fclose(fp);
fclose(fp1);
newu();
}
void charge2() ////查找函数 利用ID号进行查找信息
{
FILE *fp,*fp1;
int num,i;
printf ("请输入您要查询的员工ID号码:");
scanf ("%d",&num);
if ((fp=fopen("abc.dat","rb"))==NULL) //打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
for (i=0;i<D;i++) //利用循环的方法找到信息
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (stu[i].num == num)
{
printf ("%-5d %-6s %d %d %d \n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3 );
break;
}
}
newu();
fclose (fp);
fclose (fp1);
}
void charge()
{
int num;
printf ("按姓名查找请按1 按ID号查找请按2:");
scanf ("%d",&num);
switch (num)
{
case 1: charge1(); break;
case 2: charge2(); break;
}
}
void paixu() // 对工资进行排序
{
FILE *fp,*fp1;
int n,i,j,k;
struct Worker temp;
if ((fp=fopen("abc.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
for (n=0;n<D;n++) //利用冒泡法排序
{
fread(&stu[n],sizeof(struct Worker),1,fp);
}
for (i=0;i<D-1;i++)
{
k = i;
for (j=i+1;j<D;j++)
{
if (stu[j].salary5 > stu[k].salary5 )
k = j;
}
temp=stu[k];stu[k]=stu[i];stu[i]=temp;
}
printf ("\n\nID号码 姓名 基础工作 职务工资 住房公积金 社保金 实发工资\n");
for (i=0;i<D;i++)
{
printf ("%5d %6s %5d %4d %6d %5d %5.2f\n\n\n\n",stu[i].num ,stu[i].name ,stu[i].salary1 ,stu[i].salary2 ,stu[i].salary3,stu[i].salary4,stu[i].salary5 );
}
fclose(fp);
fclose(fp1);
newu();
}
void xiugai()
{
FILE *fp,*fp1; //fp1统计一共有fp多少组数据,fp中用来存储机体数据;
int num,i,a,b;
if ((fp=fopen("abc.dat","wb"))==NULL)//以写的方式打开文件(即对文件进行初始化)
{
printf ("cannot open file\n");//以读的方式打开文件
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,sizeof(int),1,fp1); //读出fp1中的D即是fp中的数据个数
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
}
printf ("请输入您想修改员工的ID号码:");
scanf ("%d",&num);
for (i=0;i<D;i++)
{
if (stu[i].num==num) //开始修改信息
{
printf ("ID号码是否修改(1为修改n为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("ID号码改为:");
scanf ("%d",&stu[i].num );
}
printf ("姓名是否修改(1为修改n为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("姓名改为:");
scanf ("%s",stu[i].name );
}
printf ("基础工资是否修改(1为修改2为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("基础工资改为:");
scanf ("%d",&stu[i].salary1 );
}
printf ("职务工资是否修改(1为修改2为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("职务工资改为:");
scanf ("%d",&stu[i].salary2 );
}
printf ("住房公积金是否修改(1为修改2为不修改) ");
scanf("%d",&a);
if (a==1)
{
printf ("住房公积金改为:");
scanf ("%d",&stu[i].salary3 );
}
if(stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 > 3500)
{
int a;
float b;
a = stu[i].salary1 + stu[i].salary2 - stu[i].salary3 - stu[i].salary4 - 3500;
if (a>1500&&a<4500)
{
b = (float)(a * 0.1 - 105);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
if (a>9000&&(a<4500||a==4500))
{
b = (float)(a * 0.1 - 555);
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 - b;
}
}
stu[i].salary5 = stu[i].salary1 + stu[i].salary2 ;
}
}
for(i=0;i<D;i++)
{
fwrite(&stu[i],sizeof(struct Worker),1,fp); //开始对文件进行写入数据
}
fclose(fp); //关闭文件
fclose(fp1);
printf ("是否继续修改员工信息 1继续修改 2返回菜单");
scanf ("%d",&b);
if (b==1)
xiugai();
newu();
}
void tongji()
{
FILE *fp,*fp1;
int i,n=0,m=0,o=0,p=0;//统计个数
struct Worker temp;
if ((fp=fopen("abc.dat","rb"))==NULL)//以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
printf ("\n员工信息统计如下:\n\n");
for (i=0;i<D;i++)
{
if(stu[i].salary5 > 5000) //计算工资在5000元以上的人数
{
n = n + 1;
}
else if(((stu[i].salary5==5000 )||stu[i].salary5<5000)&&stu[i].salary5 > 4000)//计算工资在4000——5000元之间的人数
{
m = m + 1;
}
else if(((stu[i].salary5==4000 )||stu[i].salary5<4000)&&stu[i].salary5 > 3000)//计算工资在3000——4000元之间的人数
{
o = o + 1;
}
else
p = p + 1; //计算工资在3000元以下的人数
}
printf ("实发工资在 5000元以上的人数为%d占总人数的百分%5.2f\n",n,(float)(100*n/D));
printf ("实发工资在3000到4000之间的人数为%d占总人数的百分%5.2f\n",m,(float)(100*m/D));
printf ("实发工资在2000到3000之间的人数为%d占总人数的百分%5.2f\n",0,(float)(100*o/D));
printf ("实发工资在 2000元以下的人数为%d占总人数的百分%5.2f\n\n\n\n",p,(float)(100*p/D));
newu();
}
void gongzhi() //对实发工资进行输出
{
int i;
FILE *fp,*fp1;
if ((fp=fopen("abc.dat","rb"))==NULL) // 以读的方式打开文件
{
printf ("cannot open file\n");
exit(0);
}
if ((fp1=fopen("abcd.dat","rb"))==NULL)
{
printf ("cannot open file\n");
exit(0);
}
fread(&D,2,1,fp1);
printf ("ID号码 姓名 实发工资\n");
for (i=0;i<D;i++)
{
fread(&stu[i],sizeof(struct Worker),1,fp);
if (stu[i].num != 0)
printf ("%5d %s %5.2f\n",stu[i].num ,stu[i].name ,stu[i].salary5 );
}
printf ("\n");
fclose(fp);
fclose(fp1);
newu();
}
int main() // 主函数
{
void input (int i);
void view(int n);
newu();
return 0;
}