北京理工大学珠海学院实验报告ZHUHAI CAMPAUS OF BEIJING INSTITUTE OF TECHNOLOGY班级:计算机(2)班 学号:100201021001 姓名:徐岩 指导教师:王日桂 成绩:实验题目:职工信息管理系统设计 实 验 时 间 : 2011年6月26日星期日 一、实验设计目的通过亲自设计程序,可以令我们熟悉C 语言操作,更熟练的掌握C 语句。
初步体会编程的过程,为将来的程序深入学习打下基础和培养兴趣。
二、实验设计要求试设计一职工信息管理系统,使之能提供以下功能:1.职工信息包括职工号、姓名、性别、年龄、学历、工资、住址、电话等(职工号不重复)。
2.系统以菜单方式工作3.职工信息录入功能(职工信息用文件保存)--输入4.职工信息浏览功能--输出5.查询和排序功能:按工资查询、按学历查询等(至少一种查询方式)--算法6.职工信息删除、修改功能(任选项)三、实验总体设计:用键盘输入职工信息:将信息写入指定文本文件:将信息从文件中导出放在结构数组中:将所有信息显示在屏幕上:按职工号查询、按学历查询、按电话查询:删除原有的职工信息录入函数写入文件 导出函数 浏览函数显示主菜单查询函数删除函数四、实验详细设计1.菜单函数menu使用printf语句在屏幕上打印出工作菜单,包括录入职工信息、浏览职工信息、查询职工信息、删除职工信息、添加职工信息、修改职工信息、退出。
2.主函数main调用菜单函数menu,显示系统工作菜单,罗列该系统所有功能。
运用do…while语句和选择函数switch即可根据使用者所输入的功能代号进入对应的功能程序。
程序开头的宏定义define N指定首次输入的职工人数为100,可根据不同需要随时更改。
3.录入函数input定义一个结构struct employee和数组em[N]用来储存N个职工的所有信息(职工号em[i].number、姓名em[i].name性别em[i].sex年龄em[i].age学历em[i].xueli工资em[i].wage住址em[i].addr电话em[i].tel)。
通过for循环输入所有职工信息。
用printf 语句提示需要输入的内容,接着用scanf语句输入相应内容。
输入完毕后套用保存函数save(m)将所输入的信息写入指定文件。
4.保存文件函数save定义文件指针fp,创建文件并用if语句判断能否打开,若fopen返回值不为0,则可继续下面操作。
用for循环通过fwrite语句将结构数组em中的内容写入保存在D盘的文本文件里面。
形参m指需要写入文件的职工人数。
最后关闭文件。
5.导出函数load首先判断文件打开是否成功,若fopen返回值不为零,继续下面操作。
用do…while循环通过fread语句将文件中的职工信息取出放到em结构数组里面。
最后关闭文件。
6.浏览函数display声明整形变量i和m,其中i记录输出的职工序数,m用来接收调用浏览函数时所传递过来的实参,接着将其值传递给导出函数load(m),使得导出的职工人数与浏览的职工人数保持一致。
通过调用load函数后(即给em数组附值),用for循环输出每个职工的各种信息。
7.删除函数del声明整形变量i,j,n,t,flag和char形数组name[20]。
调用浏览函数display(),显示所有职工信息,便于使用者审阅需删除的对象。
用printf语句提示“输入要删除的职工名字”,接着用scanf语句输入删除对象名字。
用for循环,循环主体是先判断中是否存在所输入的名字(调用字符串比较函数stecmp)。
若存在,printf语句提示是否确认删除,用scanf语句输入确认指令,再用for循环从要删除的这个职工开始,依次用后一个职工的信息覆盖前一个的。
循环结束后当前职工人数m自减1,并保存,跳出大循环;若不存在,输出“输入错误,无此人”。
printf提示下一步操作“\n继续删除请按1,不再删除请按0\n”。
switch 根据键盘输入的指令代号选择下一步连接的函数。
8.添加函数add声明整形变量i,n,m,定义文件指针fp,用追加的方式打开文件,printf提示“输入要添加的人数”scanf输入要添加的人数存放在n。
用for循环输入要添加的职工信息,浏览增加后的所有职工信息。
将输入的新信息追加写入文件保存。
关闭文件。
9.查询函数search声明整形变量t,先用printf语句显示查询菜单,用scanf输入选择的查询方式代号,用switch(t)进入所选择的具体查询函数,包括按职工号查询、按学历查询、按电话查询三中方式。
10.按职工号查询search_num声明两个整形变量:i记录职工的序数,num存放键盘输入的职工号。
调用导出函数load()表示当前的职工人数。
通过scanf语句从键盘输入需要查询的职工号,并赋值给num。
用for 循环,循环主体是先判断em.num中是否有输入的职工号,如果有,用printf语句输出与职工号相对应的该职工所有信息,再跳出循环;如果没有,输出“查无此人”,并调用search()返回查询菜单。
按学列查询和按电话查询与此方法类似,就不多说,以下只附按职工号查询程序流程图。
五、调试与测试整个程序代码是分块书写的,每个函数都可以独立运行。
只有输入函数查询、菜单函数写得很顺利,一次性就能够成功运行,其他函数在调试过程中或多或少都出现了问题。
而且串联所有函数时,调试提示出错:有几个函数“redefinition; different basic types”解决:在函数名前加void指明类型。
1.保存函数save()在调试和链接的时候都没有出现错误提示,但在运行的时候出现了问题。
写入指定位置的文件,打开后总会有乱码。
与c语言课本上的例题对照后发现,我写的fopen 指向的文件没有指定文件的存储类型。
2.导出函数load()遇到一个问题。
是用fscanf语句时,漏写地址符。
调试和链接都没问题,但点击运行后,总出现一个提示出错的蓝色小窗口。
经过网上的查询发现了原因所在。
解决:在em[i].name等之前加上地址符。
齐。
即下面的职工信息分别与第一个printf输出的中文项目提示对齐。
解决方法:不断修改空格个数,不断运行察看效果。
4.按学历查询函数search_xueli(),要考虑输入一种学历,可能对应出很多职工,这就不能延用按姓名和职工号查询中判断是否输入错误的方法了。
为了显示出所有具有该学历的职工,就需要让for循环一直运行到最后一个为止。
这时计量数i始终会等于职工人数,不能再用i来判断是否不存在此人。
这就需要再定一个整形变量k,用来计量单独的一个循环次数。
5.删除函数del()的难点在于多次删除。
即在删除掉第一个人以后,现有职工人数发生改变,而宏定义中的N却是不变的。
最开始我想到了用static定义一个整形变量a来计量当前人数。
这在单独运行删除函数时,可以成功的连续删除。
最后所有函数串在一起时,有了更好的解决方法—指针。
6.添加函数add()遇到的问题是用printf输入新职工信息后,保存到文件里面,发现原有的信息不见了。
解决:文件打开方式改用"a"追加写入。
六、源程序代码#include<stdio.h>#include<windows.h>#include<time.h>#include<string.h>#define N 100struct employee{int num;char name[10];char sex;int age;char xueli[30];int wage;char addr[30];long int tel;}em[100]; /*定义一个结构体*/void menu();void input();void save(int);void display();void del();void add();void search_num();void search_xueli();void search_tel();void modify(); /*定义各函数*/void menu() /*菜单函数*/{printf("\n");printf("\n");printf(" ******************职工信息管理****************\n");printf(" 1.录入职工信息");printf(" 2.浏览职工信息\n");printf(" 3.查询职工信息");printf(" 4.删除职工信息\n");printf(" 5.添加职工信息");printf(" 6.修改职工信息\n");printf(" 7.退出\n");printf(" ********************谢谢使用******************\n");printf("\n");printf("\n");}void main(){menu(); /*调用菜单函数*/int n,flag;char a;do{printf("请选择你需要操作的步骤(1--7):\n");scanf("%d",&n);if(n>=1&&n<=7){flag=1;break;}else{flag=0;printf("您输入有误,请重新选择!");}}while(flag==0);while(flag==1){switch(n){case 1:printf(" ◆◆◆输入职工信息◆◆◆\n");printf("\n");input();break;case 2:printf(" ◆◆◆浏览职工信息◆◆◆\n");printf("\n");display();break;case 3:printf(" ◆◆◆按职工号查询职工信息◆◆◆\n");printf("\n");search();break;case 4:printf(" ◆◆◆删除职工信息◆◆◆\n");printf("\n");del();break;case 5:printf(" ◆◆◆添加职工信息◆◆◆\n");printf("\n");add();break;case 6:printf(" ◆◆◆修改职工信息◆◆◆\n");printf("\n");modify();break;case 7:exit(0);break;default :break;}getchar();printf("\n");printf("是否继续进行(y or n):\n");scanf("%c",&a);if(a=='y'){flag=1;system("cls"); /*清屏*/menu(); /*调用菜单函数*/printf("请再次选择你需要操作的步骤(1--6):\n");scanf("%d",&n);printf("\n");}elseexit(0);}}void input() /*录入函数*/{int i,m;printf("请输入需要创建信息的职工人数(1--100):\n");scanf("%d",&m);for (i=0;i<m;i++){printf("职工号: ");srand((int)time(0));em[i].num=rand()%10000+20000000;if(em[i].num!=em[i-1].num)printf("%8d ",em[i].num);printf("\n");printf("请输入姓名: ");scanf("%s",em[i].name);getchar();printf("请输入性别(f--女 m--男): ");scanf("%c",&em[i].sex);printf("请输入年龄: ");scanf("%d",&em[i].age);printf("请输入学历: ");scanf("%s",em[i].xueli);printf("请输入工资: ");scanf("%d",&em[i].wage);printf("请输入住址: ");scanf("%s",em[i].addr);printf("请输入电话: ");scanf("%d",&em[i].tel);printf("\n");}printf("\n创建完毕!\n");save(m);}void save(int m) /*保存文件函数*/{int i;FILE*fp;if((fp=fopen("employee_list","wb"))==NULL) /*创建文件并判断是否能打开*/ {printf ("cannot open file\n");exit(0);}for (i=0;i<m;i++) /*将内存中职工的信息输出到磁盘文件中去*/if (fwrite(&em[i],sizeof(struct employee),1,fp)!=1)printf("file write error\n");fclose(fp);}int load() /*导出函数*/{FILE*fp;int i=0;if((fp=fopen("employee_list","rb"))==NULL){printf ("cannot open file\n");exit(0);}else{do{fread(&em[i],sizeof(struct employee),1,fp);i++;}while(feof(fp)==0);}fclose(fp);return(i-1);}void display() /*浏览函数*/{int i;int m=load();printf("\n 职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n");for(i=0;i<m;i++) /*m为输入部分的职工人数*/printf("\n %d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].se x,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel);}void del() /*删除函数*/{int m=load();int i,j,n,t,flag;char name[20];printf("\n 原来的职工信息:\n");display(); /* 调用浏览函数*/printf("\n");printf("请输入要删除的职工的姓名:\n");scanf("%s",name);for(flag=1,i=0;flag&&i<m;i++){if(strcmp(em[i].name,name)==0){printf("\n已找到此人,原始记录为:\n");printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n");printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex, em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel);printf("\n确实要删除此人信息请按1,不删除请按0\n");scanf("%d",&n);if(n==1) /*如果删除,则其他的信息都往上移一行*/{for(j=i;j<m-1;j++){strcpy(em[j].name,em[j+1].name);em[j].num=em[j+1].num;em[j].sex=em[j+1].sex;em[j].age=em[j+1].age;strcpy(em[j].xueli,em[j+1].xueli);em[j].wage=em[j+1].wage;strcpy(em[j].addr,em[j+1].addr);em[j].tel=em[j+1].tel;}flag=0;}}}if(!flag)m=m-1;elseprintf("\n对不起,查无此人!\n");printf("\n 浏览删除后的所有职工信息:\n");save(m); /*调用保存函数*/display(); /*调用浏览函数*/printf("\n继续删除请按1,不再删除请按0\n");scanf("%d",&t);switch(t){case 1:del();break;case 0:break;default :break;}}void add() /*添加函数*/{FILE*fp;int n;int count=0;int i;int m=load();printf("\n 原来的职工信息:\n");display(); /* 调用浏览函数*/printf("\n");fp=fopen("emploee_list","a");printf("请输入想增加的职工数:\n");scanf("%d",&n);for (i=m;i<(m+n);i++){printf("\n 请输入新增加职工的信息:\n");printf("请输入职工号: ");srand((int)time(0));em[i].num=rand()%10000+20000000;if(em[i].num!=em[i-1].num)printf("%8d ",em[i].num);printf("\n");printf("请输入姓名: ");scanf("%s",em[i].name);getchar();printf("请输入性别(f--女 m--男): ");scanf("%c",&em[i].sex);printf("请输入年龄: ");scanf("%d",&em[i].age);printf("请输入学历: ");scanf("%s",em[i].xueli);printf("请输入工资: ");scanf("%d",&em[i].wage);printf("请输入住址: ");scanf("%s",em[i].addr);printf("请输入电话: ");scanf("%d",&em[i].tel);printf("\n");count=count+1;printf("已增加的人数:\n");printf("%d\n",count);}printf("\n添加完毕!\n");m=m+count;printf("\n浏览增加后的所有职工信息:\n");printf("\n");save(m);display();fclose(fp);}void search() /*查询函数*/{int t,flag;do{printf("\n按职工号查询请按1 ; 按学历查询请按2 ; 按电话号码查询请按3,进入主函数按4\n");scanf("%d",&t);if(t>=1&&t<=4){flag=1;break;}else{flag=0;printf("您输入有误,请重新选择!");}}while(flag==0);while(flag==1){switch(t){case 1:printf("按职工号查询\n");search_num();break;case 2:printf("按学历查询\n");search_xueli();break;case 3:printf("按电话号码查询\n");search_tel();break;case 4:main();break;default:break;}}}void search_num(){int num;int i,t;int m=load();printf("请输入要查找的职工号(20001111---20009999):\n");scanf("%d",&num);for(i=0;i<m;i++)if(num==em[i].num){printf("\n已找到此人,其记录为:\n");printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n");printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex, em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel);break;}if(i==m)printf("\n对不起,查无此人\n");printf("\n");printf("返回查询函数请按1,继续查询职工号请按2\n");scanf("%d",&t);switch(t){case 1:search();break;case 2: break;default:break;}}void search_xueli(){char xueli[30];int i,t;int m=load();printf("请输入要查找的学历:\n");scanf("%s",xueli);for(i=0;i<m;i++)if(strcmp(em[i].xueli,xueli)==0){printf("\n已找到,其记录为:\n");printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n");printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex, em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel);}if(i==m)printf("\n对不起,查无此人\n");printf("\n");printf("返回查询函数请按1,继续查询学历请按2\n");scanf("%d",&t);switch(t){case 1:search();break;case 2:break;default :break;}}void search_tel(){long int tel;int i, t;int m=load();printf("请输入要查找的电话号码:\n");scanf("%ld",&tel);for(i=0;i<m;i++)if(tel==em[i].tel){printf("\n已找到此人,其记录为:\n");printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n");printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex, em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel);break;}if(i==m)printf("\n对不起,查无此人\n");printf("\n");printf("返回查询函数请按1,继续查询电话号码请按2\n");scanf("%d",&t);switch(t){case 1:search();break;case 2:break;default :break;}}void modify() /*修改函数*/{int num;char name[10];char sex;int age;char xueli[30];int wage;char addr[30];long int tel;int b,c,i,n,t,flag;int m=load(); /*导入文件内的信息*/printf("\n 原来的职工信息:\n");display(); /* 调用浏览函数*/printf("\n");printf("请输入要修改的职工的姓名:\n");scanf("%s",name);for(flag=1,i=0;flag&&i<m;i++){if(strcmp(em[i].name,name)==0){printf("\n已找到此人,原始记录为:\n");printf("\n职工号\t姓名\t性别\t年龄\t学历\t工资\t住址\t电话 \n");printf("\n%d\t%s\t%c\t%d\t%s\t%d\t%s\t%ld\n",em[i].num,em[i].name,em[i].sex,em[i].age,em[i].xueli,em[i].wage,em[i].addr,em[i].tel);printf("\n确实要修改此人信息请按1 ; 不修改请按0\n");scanf("%d",&n);if(n==1){printf("\n需要进行修改的选项\n 1.职工号 2.姓名 3.性别 4.年龄 5.学历 6.工资 7.住址 8.电话\n");printf("请输入你想修改的那一项序号:\n");scanf("%d",&c);if(c>8||c<1)printf("\n选择错误,请重新选择!\n");}flag=0;}}if(flag==1)printf("\n对不起,查无此人!\n");do{switch(c) /*因为当找到第i个职工时,for语句后i自加了1,所以下面的应该把改后的信息赋值给第i-1个人*/{case 1:printf("职工号改为: ");scanf("%d",&num);em[i-1].num=num;break;case 2:printf("姓名改为: ");scanf("%s",name);strcpy(em[i-1].name,name);break;case 3:printf("性别改为: ");getchar();scanf("%c",&sex);em[i-1].sex=sex;break;case 4:printf("年龄改为: ");scanf("%d",&age);em[i-1].age=age;break;case 5:printf("学历改为: ");scanf("%s",xueli);strcpy(em[i-1].xueli,xueli);break;case 6:printf("工资改为: ");scanf("%d",wage);break;case 7:printf("住址改为: ");scanf("%s",addr);strcpy(em[i-1].addr,addr);break;case 8:printf("电话改为: ");scanf("%ld",&tel);em[i-1].tel=tel;break;}printf("\n");printf("\n是否确定所修改的信息?\n 是请按1 ; 不,重新修改请按2: \n");scanf("%d",&b);}while(b==2);printf("\n浏览修改后的所有职工信息:\n");printf("\n");save(m);display();printf("\n继续修改请按1,不再修改请按0\n");scanf("%d",&t);switch(t){case 1:modify();break;case 0:break;default :break;}}七、执行结果。