1、 会议签到系统课程设计 31 2020年5月29日 文档仅供参考 ...../ 沈 阳 航 空 工 业 学 院 课程设计 学 号 04021035 班 级 6402101 姓 名 赵晨 指导教师 王晓岩 9 月 20 日 沈阳航空工业学院 课程设计任务书 院系:电子 专业:电子信息工程 班级:6402101 学号: 04021035 题目:会议签到系统 一、课程设
2、计时间 9月10日至 9月14日,共计1周,20学时。 二、课程设计内容 用C语言编写软件完成以下任务: (1)数据信息(参加会议人员代号,姓名,性别,工作单位,职务,联系方式,是否签到等)保存在meeting.dat文件中。 (2)签到。 (3)按工作单位将数据信息排序。 (4)统计实际参加会议的人数和缺席的人数。 三、课程设计要求 1. 程序质量: ² 贯彻结构化的程序设计思想。 ² 用户界面友好,功能明确,操作方便。 ² 用户界面中的菜单至少应包括”名单录入”、”人员签到”、”数据排序”、”统计参加和缺席人数”、”退出”5项,所有数据的改变都应该在相关文件中有所
3、体现。 ² 代码应适当缩进,并给出必要的注释,以增强程序的可读性。 2. 课程设计说明书: 课程结束后,上交课程设计说明书和源程序。课程设计说明书的格式和内容参见提供的模板。 四、指导教师和学生签字 指导教师:________ 学生签名:________ 五、说明书成绩 六、教师评语 目录 一、需求分析 1 二、程序流程图 2 三、核心技术的实现说明及相应程序段 9 四、个人总结 15 五、参考文献 15 六、源程序 16 一、需求分析 经过对程序设计题目的分析可知,整个程序的设计实现大致分为三个模块,其中每一个模
4、块对应一个函数,她们的功能分别是:录入参加会议人员信息数据函数(add),人员签到数据函数(signin),排序函数(compositor)。在这些函数当中,录入信息和排序函数的实现严格按照题目的要求,而签到和统计参加人数和缺席人数都放到了函数(signin)里。 1、录入参加会议人员信息数据函数 主要实现程序最初运行时参加会议人员信息数据的录入以及其后的运行中人员数据的追加功能; 2、人员签到数据函数 实现的功能是按照参加会议人员的代号对人员进行签到,并对签到人员进行标记,最后统计并输出参加人数和缺席人数。 3、排序函数 实现的功能是按照人员代号的增序显示。 除上面介绍
5、的功能之外,程序还具有退出功能,能够在程序运行完毕后选择退出。 每一个参加会议人员信息都包含参加会议人员代号,姓名,性别,工作单位,职务,联系方式,是否签到,在程序当中,将人员信息类型定义为结构体类型,添加以及追加的人员信息直接写入D盘的meeting.dat文件中,其它函数每次对人员记录的访问,其数据来源都是meeting.dat文件,这样做不但能够保证人员数据的一致性,而且能够对人员数据进行永久保存,保证每次运行程序都能够采用原来的数据。 二、程序流程图 1、程序总体结构图 2、具体功能框图 (1)录入人员数据函数add 开始 定义文件指针 定义头指针
6、 链表信息存入文件 输入信息到链表 结束 图2 录入人员数据函数 (2)人员签到函数signin 开始 定义变量初值,文件指针,链表指针 能否打开文件 输出不能打开文件 结束 否 feof(f1) 是 将文件中的信息读入链表 释放P指针 否 关闭f1文件 a=0 输出:请员工输入序号签到,输入0时结束签到 否 是 是 输入%d 是 M是否为空 否 i++ 输出结束签到,人员出勤结果如下 输出应到%d人,实到%d人,缺席%d
7、人,j,i,j-i 结束 图3人员签到函数 3)按代号排序函数compositor 开始 定义文件指针,链表指针 能否打开文件 meeting1.dat !feof(f1) 定义指针n 输出:不能打开文件 输出:不能打开文件 将信息输入链表 释放指针 r=top 结束 结束 能否打开文件 meeting2.dat P是否为零 否 能 否 能 否 是 是 否 否 r指针内容小于p内容且r!=p 是 r=r->next r!=p 否 是
8、 q=p;p=p0 否 r==top q->next=r;r0->next=q 是 q->next=top;top=q p0=p;p=p->next p=NULL;p=top, 否 P不为空 是 输出链表中的信息 关闭文件f1,f2 结束 图4按代号排序函数 三、核心技术的实现说明及相应程序段 本程序主要由三个自定义函数和一个主函数组成,其中主函数以菜单的形式调用其它函数来实现要求的所有功能。在
9、这些函数当中,录入数据函数、签到函数和排序函数是程序中较为核心的部分,下面分别进行说明。 1、录入数据函数 录入数据分为两种情况,其一是在会议文件(meeting.dat)不存在的情况下,首先由程序创立一个新文件,并将录入的人员信息写入该文件当中;其二是在会议文件(meeting.dat)已经存在的情况下,此时文件要以读写方式或追加的方式打开,这样才能够保证以前已经存在的数据不丢失。具体的程序段如下: void add(){ /*录入员工信息子函数*/ FILE *f1; finger top=NULL,p=NULL,t=NULL; p=(finger)ma
10、lloc(sizeof(message)); top=p; while(1){ printf("\n请输入员工信息,输入0时结束录入"); scanf("%d%s%s%s%s%d",&p->number,p->name,p->sex,p->workplace,p->job,&p->tel); /*分部分输入*/ p->flag=0; if(p->number==0){ free(p); t->next=NULL; break; } t=p; p=(finger)malloc(sizeof(message));
11、 t->next=p; } p=NULL; if((f1=fopen("D:\\meeting.dat","w"))==NULL){ /*把链表中信息存入文件*/ printf("不能创立文件!!"); exit(0); } p=top; while(p!=NULL){ fprintf(f1,"%d %s %s %s %s %d\n",p->number,p->name,p->sex,p->workplace,p->job,p->tel); p=p->next; } } 2、人员签到函数 该函
12、数的核心内容是人员签到和统计参加人数和缺席人数。该函数执行时,首先把meeting.dat文件中信息读入链表,并由用户输入人员代号,而后按0结束签到。如果文件中存在该人员的数据,则进行标记,否则不标记。这时被标记的为1,未被标记的为0,最后统计出参加人数和缺席人数,具体程序段如下: void signin(){ /*签到,标记*/ int a=1,i=0,j=0; FILE *f1; finger m=NULL,p=NULL,t=NULL,top=NULL; if((f1=fopen("D:\\meeting.dat","r"))==NULL){ /*把文件中信息读入链
13、表*/ printf("不能打开文件meeting.dat!"); exit(0); } p=(finger)malloc(sizeof(message)); top=p; while(!feof(f1)){ fscanf(f1,"%d%s%s%s%s%d\n",&p->number,p->name,p->sex,p->workplace,p->job,&p->tel); p->flag=0; t=p; p=(finger)malloc(sizeof(message)); t->next=p; } free(p); t->n
14、ext=NULL; fclose(f1); m=top; while(a!=0){ /*签到*/ printf("请员工输入序号签到,输入0时结束签到"); scanf("%d",&a); while(m!=NULL){ if(m->number==a){ m->flag=1;i++; } m=m->next; j++; } } printf("结束签到,人员出勤结果如下:\n"); printf("应到%d人,实到%d人,缺勤%d人\n",j,i,j-i); } 3、按代号排序函数 对
15、于代号的排序采用的排序算法是链表插入法,首先读取文件meeting.dat信息,在创立meeting2.dat文件,以便保存排序后的信息,该程序的实现主要是把指针变量插入到各个结点,进行比较,最终实现按代号的升序排列。具体的程序段如下: void compositor(){ /*排序*/ FILE *f1; FILE *f2; finger m=NULL,n=NULL,t=NULL,top=NULL,p,p0,r,r0,q; if((f1=fopen("D:\\meeting.dat","r"))==NULL){ /*读取文件meeting.dat信息*/
16、printf("不能打开文件meeting.dat!"); exit(0); } if((f2=fopen("D:\\meeting2.dat","w"))==NULL){ /*创立meeting2.dat文件*/ printf("不能创立文件meeting2.dat!"); exit(0); } n=(finger)malloc(sizeof(message)); top=n; while(!feof(f1)){ /*排序*/ fscanf(f1,"%d%s%s%s%s%d\n",&n->number,n->name,n->sex,n
17、>workplace,n->job,&n->tel);
n->flag=0;
t=n;
n=(finger)malloc(sizeof(message));
t->next=n;
}
free(n); /**/
t->next=NULL;
p0=NULL;
p=top;
while(p!=NULL){
r=top;
while((r->number
18、t; p=p0; if(r==top){ q->next=top; top=q; } else{ q->next=r; r0->next=q; } } p0=p; p=p->next; } p=NULL; p=top; while(p!=NULL){ /*将排序后信息写入文件meeting2.dat*/ fprintf(f2,"%d %s %s %s %s %d\n",p->number,p->name,p->sex,p->workplace,p->job
19、p->tel); printf("%d %s %s %s %s %d\n",p->number,p->name,p->sex,p->workplace,p->job,p->tel); p=p->next; } fclose(f1); fclose(f2); } 四、个人总结 一周的课程设计使我更一深层次地学习了C语言,了解了C语言,曾经课本没有认真地阅读,现在经过这门课程,使我不但认真地看,重复地看,而且还仔细地研究了一翻,补上了以前学习的漏洞,刚开始时认为这门课程很难,可是经过了一翻研究和与老师和其它同学的沟通,一些问
20、题还是解决了,但能够说这门课程还是有难度的,因此以后还要加强对这方面知识的学习,掌握好这门课程对我以后的专业也有很大的好处。
程序大致上完成了课程的要求,但还是有些毛病不能解决,主函数不是总是循环的结构,如果改成这种结构,签到和排序都出问题,可能问题出现在我程序的各个部分都是我在书上找的,然后拼接在一起的,各个部分的连贯性不好,导致改后出错。
五、参考文献
1 谭浩强.C程序设计.北京:清华大学出版社,
2 刘成等.C语言程序设计实验指导与习题集.北京:中国铁道出版社,
六、源程序
#include
21、de
22、\n"); printf("**1.录入员工信息 **\n"); printf("**2.在此签到,并输出人员签到结果 **\n"); printf("**3.排序
23、 **\n"); printf("**4.退出 **\n"); printf("********************************************************************************\n"); } void add(){ /*录入员工信息子函数*/ FILE *f1; finger to
24、p=NULL,p=NULL,t=NULL; p=(finger)malloc(sizeof(message)); top=p; while(1){ printf("\n请输入员工信息,输入0时结束录入"); scanf("%d%s%s%s%s%d",&p->number,p->name,p->sex,p->workplace,p->job,&p->tel); /*分部分输入*/ p->flag=0; if(p->number==0){ free(p); t->next=NULL; break; } t=p;
25、 p=(finger)malloc(sizeof(message)); t->next=p; } p=NULL; if((f1=fopen("D:\\meeting.dat","w"))==NULL){ /*把链表中信息存入文件*/ printf("不能创立文件!!"); exit(0); } p=top; while(p!=NULL){ fprintf(f1,"%d %s %s %s %s %d\n",p->number,p->name,p->sex,p->workplace,p->job,p->tel);
26、 p=p->next; } } void signin(){ /*签到,标记*/ int a=1,i=0,j=0; FILE *f1; finger m=NULL,p=NULL,t=NULL,top=NULL; if((f1=fopen("D:\\meeting.dat","r"))==NULL){ /*把文件中信息读入链表*/ printf("不能打开文件meeting.dat!"); exit(0); } p=(finger)malloc(sizeof(message)); top=p; while(!feof(f1)){
27、 fscanf(f1,"%d%s%s%s%s%d\n",&p->number,p->name,p->sex,p->workplace,p->job,&p->tel); p->flag=0; t=p; p=(finger)malloc(sizeof(message)); t->next=p; } free(p); t->next=NULL; fclose(f1); m=top; while(a!=0){ /*签到*/ printf("请员工输入序号签到,输入0时结束签到"); scanf("%d",&a); while
28、m!=NULL){ if(m->number==a){ m->flag=1;i++; } m=m->next; j++; } } printf("结束签到,人员出勤结果如下:\n"); printf("应到%d人,实到%d人,缺勤%d人\n",j,i,j-i); } void compositor(){ /*排序*/ FILE *f1; FILE *f2; finger m=NULL,n=NULL,t=NULL,top=NULL,p,p0,r,r0,q; if((f1=fopen("D:\\meetin
29、g.dat","r"))==NULL){ /*读取文件meeting.dat信息*/ printf("不能打开文件meeting.dat!"); exit(0); } if((f2=fopen("D:\\meeting2.dat","w"))==NULL){ /*创立meeting2.dat文件*/ printf("不能创立文件meeting2.dat!"); exit(0); } n=(finger)malloc(sizeof(message)); top=n; while(!feof(f1)){ /*排序*/ fscanf(
30、f1,"%d%s%s%s%s%d\n",&n->number,n->name,n->sex,n->workplace,n->job,&n->tel);
n->flag=0;
t=n;
n=(finger)malloc(sizeof(message));
t->next=n;
}
free(n); /**/
t->next=NULL;
p0=NULL;
p=top;
while(p!=NULL){
r=top;
while((r->number
31、 } if(r!=p){ q=p; p0->next=p->next; p=p0; if(r==top){ q->next=top; top=q; } else{ q->next=r; r0->next=q; } } p0=p; p=p->next; } p=NULL; p=top; while(p!=NULL){ /*将排序后信息写入文件meeting2.dat*/ fprintf(f2,"%d %s %s %s %s %d\
32、n",p->number,p->name,p->sex,p->workplace,p->job,p->tel); printf("%d %s %s %s %s %d\n",p->number,p->name,p->sex,p->workplace,p->job,p->tel); p=p->next; } fclose(f1); fclose(f2); } void main(){ /*主函数*/ int x= 0; while(x!='4'){ menu(); printf("请选择要进行的操作,用数字键选择:"); scanf("%d",&x); switch(x){ case 1:add(); break; case 2:signin(); break; case 3:compositor(); break; } exit(0); } }






