C语言程序设计报告班级学生成绩管理系统.doc
C语言程序设计课程设计报告设计题目:班级学生成绩管理系统专 业: 班 级: 学 号: 姓 名: 指导教师: 时间:2011/06/12 目 录一、 课程设计目的和要求3二、 课程设计任务内容4三、 程序流程图16四、 软件使用说明17五、 课程设计心得与体会19一. 课程设计的目的和要求目的:本课程设计是计算机科学与技术专业重要的实践性环节之一,是在学生学习完程序设计语言(C)课程后进行的一次全面的综合练习。本课程设计的目的和任务:1. 巩固和加深学生对C语言课程的基本知识的理解和掌握2. 掌握C语言编程和程序调试的基本技能3. 利用C语言进行基本的软件设计4. 掌握书写程序设计说明文档的能力5. 提高运用C语言解决实际问题的能力 程序功能和要求:1. 学生记录用结构体2. 学生信息数据用文件保存3. 采用多文件形式组织程序4. 基本功能:1) 增加学生记录2) 文件存储3) 读取文件4) 删除记录 5) 修改记录6) 查询记录 5.程序简洁易懂二课程设计任务和内容代码:#ifndef H_STUDENT_HH#define H_STUDENT_HH#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<string.h>#define NUM_SUBJECT 5 /科目数#define INITIAL_SIZE 100 /数组初始大小#define INCR_SIZE 50 /数组每次增加的大小struct student_infochar number15; /学号char name20; /姓名char gender4; /性别float scoreNUM_SUBJECT; /某学生的各科成绩float sum; /总分float average; /平均分int index; /名次;typedef struct student_info StuInfo;extern int numStus; /记录的学生数extern StuInfo* records; /记录学生信息的数组extern char savedTag; /信息是否保存extern int arraySize; /数组大小extern char* subject;void handle_menu(void);int menu_select(void);void addRecord(void);void modifyRecord(void);void display(void);void queryInfo(void);void removeRecord(void);int saveRecords(void);int loadRecords(void);void quit(void);void showTable(void);int findRecord(char* target,int targetType,int from);void copyRecord(StuInfo* src,StuInfo* dest);void sortInfo(void);int findRecord(char* target,int targetType,int from);int getIndex(float);#endif / H_STUDENT_HH#include "student.h"/*输出表头*void showTable(void)int j;printf("学号t姓名t性别");for(j=0;j<NUM_SUBJECT;j+)printf(" %s ",subjectj);printf(" 总分 平均分 名次n");/*显示所有学生信息函数*void display(void)int i,j;if(numStus=0)printf("没有可供显示的记录!");return;showTable();for(i=0;i<numStus;i+)printf("%4st%3st%3s",recordsi.number,recordsi.name,recordsi.gender);for(j=0;j<NUM_SUBJECT;j+)printf(" %.1f ",recordsi.scorej);printf(" %.1f %.1f %dn",recordsi.sum,recordsi.average,recordsi.index);if(i%19=0 && i!=0)printf("输入一行字符后继续.n");getch();printf("nn");showTable();/*在当前表的末尾增加新的信息*void addRecord(void)char str10;int j;float mark,sum;if(numStus=0)printf("原来没有记录,现在建立新表n");elseprintf("先面在当前的末尾增加新的信息n");while(1)printf("您将要添加一组信息,确定吗?(y/n)");gets(str);if(str0='n' | str0='N')break;if(numStus >= arraySize)records=realloc(records,(arraySize+INCR_SIZE)*sizeof(StuInfo);if(records=NULL)printf("memory falled!");exit(-1);arraySize=arraySize+INCR_SIZE;printf("请输入学号:");gets(recordsnumStus.number);printf("请输入姓名:");gets(recordsnumStus.name);printf("请输入性别(0为女,1为男):");gets(str);if(str0='0')strcpy(recordsnumStus.gender,"女");elsestrcpy(recordsnumStus.gender,"男");sum=0;for(j=0;j<NUM_SUBJECT;j+)printf("请输入%s成绩:",subjectj);gets(str);mark=(float)atof(str);recordsnumStus.scorej=mark;sum+=mark;recordsnumStus.sum=sum;recordsnumStus.average=sum/NUM_SUBJECT;recordsnumStus.index=getIndex(sum);numStus+;printf("现在一共有%d条信息n",numStus);savedTag=1;/*找出总分为sum在第0至numStus-1个记录中按升序排序的位置*int getIndex(float sum)int i;int count=0;for(i=0;i<numStus;i+)if(recordsi.sum<sum)recordsi.index+;else if(recordsi.sum>sum)count+;return count+1;#include "student.h"/*文件存储操作函数*int saveRecords(void)FILE *fp;char fname30;if(numStus=0)printf("没有记录可存!");return -1;printf("请输入要存入的文件名(直接回车选择文件stu_info):");gets(fname);if(strlen(fname)=0)strcpy(fname,"stu_info");if(fp=fopen(fname,"wb")=NULL)printf("不能存入文件!n");return -1;printf("n存文件.n");fwrite(records,sizeof(StuInfo)*numStus,1,fp);fclose(fp);printf("%d条记录已经存入文件,请继续操作。n",numStus);savedTag=0;return 0;/*文件读取操作函数*int loadRecords(void)FILE *fp;char fname30;char str5;if(numStus!=0 && savedTag=0)printf("请选择您是要覆盖现有记录(y),还是要将");printf("读取的记录添加到现有记录之后(n)?n");printf("直接回车则覆盖现有记录n");gets(str);if(str0='n'|str0='N')savedTag=1;elseif(savedTag=1)printf("读取文件将会更改原来的记录,");printf("是否保存原来记录?(y/n)");gets(str);if(str0!='n'&&str0!='N')saveRecords();numStus=0;printf("请输入要读取的文件名(直接回车选择文件stu_info):");gets(fname);if(strlen(fname)=0)strcpy(fname,"stu_info");if(fp=fopen(fname,"rb")=NULL)printf("打不开文件!请重新选择'n");return -1;printf("n取文件.n");while(!feof(fp)if(numStus>=arraySize)records=realloc(records,(arraySize+INCR_SIZE)*sizeof(StuInfo);if(records=NULL)printf("memory failed!");exit(-1);arraySize=arraySize+INCR_SIZE;if(fread(&recordsnumStus,sizeof(StuInfo),1,fp)!=1) break;/按照addRecord函数的方法,更新名次recordsnumStus.index = getIndex(recordsnumStus.sum);numStus+;fclose(fp);printf("现在共有%d条记录。",numStus);return 0;#include "student.h"/*文件存储操作函数*int saveRecords(void)FILE *fp;char fname30;if(numStus=0)printf("没有记录可存!");return -1;printf("请输入要存入的文件名(直接回车选择文件stu_info):");gets(fname);if(strlen(fname)=0)strcpy(fname,"stu_info");if(fp=fopen(fname,"wb")=NULL)printf("不能存入文件!n");return -1;printf("n存文件.n");fwrite(records,sizeof(StuInfo)*numStus,1,fp);fclose(fp);printf("%d条记录已经存入文件,请继续操作。n",numStus);savedTag=0;return 0;/*文件读取操作函数*int loadRecords(void)FILE *fp;char fname30;char str5;if(numStus!=0 && savedTag=0)printf("请选择您是要覆盖现有记录(y),还是要将");printf("读取的记录添加到现有记录之后(n)?n");printf("直接回车则覆盖现有记录n");gets(str);if(str0='n'|str0='N')savedTag=1;elseif(savedTag=1)printf("读取文件将会更改原来的记录,");printf("是否保存原来记录?(y/n)");gets(str);if(str0!='n'&&str0!='N')saveRecords();numStus=0;printf("请输入要读取的文件名(直接回车选择文件stu_info):");gets(fname);if(strlen(fname)=0)strcpy(fname,"stu_info");if(fp=fopen(fname,"rb")=NULL)printf("打不开文件!请重新选择'n");return -1;printf("n取文件.n");while(!feof(fp)if(numStus>=arraySize)records=realloc(records,(arraySize+INCR_SIZE)*sizeof(StuInfo);if(records=NULL)printf("memory failed!");exit(-1);arraySize=arraySize+INCR_SIZE;if(fread(&recordsnumStus,sizeof(StuInfo),1,fp)!=1) break;/按照addRecord函数的方法,更新名次recordsnumStus.index = getIndex(recordsnumStus.sum);numStus+;fclose(fp);printf("现在共有%d条记录。",numStus);return 0;#include "student.h"/*学生信息排序函数*void sortInfo(void)char str5;int i,j;StuInfo tmps;if(numStus=0)printf("没有可供排序的记录!");return; printf("请输入您希望进行排序的方式:n");printf("1.按学号进行升序排序n");printf("2.按学号进行降序排序n");printf("3.按姓名进行升序排序n");printf("4.按姓名进行降序排序n");printf("5.按名次进行升序排序n");printf("6.按名次进行降序排序n");printf("7.按错了,现在并不想进行排序n");gets(str);if(str0<'1'|str0>'6') return;/进行排序for(i=0;i<numStus-1;i+)for(j=i+1;j<numStus;j+)if(str0='1' && strcmp(recordsi.number,recordsj.number)>0) |(str0='2' && strcmp(recordsi.number,recordsj.number)<0) |(str0='3' && strcmp(recordsi.name,recordsj.name)>0) |(str0='4' && strcmp(recordsi.name,recordsj.name)<0) |(str0='5' && recordsi.index>recordsj.index) |(str0='6' && recordsi.index<recordsj.index)copyRecord(&recordsi,&tmps);copyRecord(&recordsj,&recordsi);copyRecord(&tmps,&recordsj);printf("排序已经完成n");savedTag=1;#include "student.h"/初始化int numStus=0; /记录学生数StuInfo *records=NULL; /记录学生信息char savedTag=0; /信息保存标志,1为未保存,0为已保存int arraySize; /数组大小char* subject="高数","英语","线代","物理","电工","体育"/*主函数*int main()records=(StuInfo*)malloc(sizeof(StuInfo)*INITIAL_SIZE);if(records=NULL)printf("memory fall!");exit(-1);arraySize=INITIAL_SIZE;printf("n");printf("t*n");printf("t* 这是一个 *n");printf("t* 学生成绩管理程序 *n");printf("t* 可以对学生成绩进行管理 *n");printf("t* 欢迎使用管理系统 *n");printf("t*n");printf("n");handle_menu();/*菜单处理函数*void handle_menu(void)for(;)switch(menu_select()case 1:addRecord();break;case 2:modifyRecord();break;case 3:display();break;case 4:queryInfo();break;case 5:removeRecord();break;case 6:saveRecords();break;case 7:loadRecords();break;case 8:sortInfo();break;case 9:quit();/*菜单选择函数*int menu_select()char s2;int cn=0;printf("n");printf("t1.增加学生信息n");printf("t2.修改学生信息n");printf("t3.显示学生信息n");printf("t4.查询学生信息n");printf("t5.删除学生信息n");printf("t6.保存学生信息至记录文件n");printf("t7.从记录文件读取学生信息n");printf("t8.排序学生信息n");printf("t9.结束运行n");printf("n左边数字对应功能选择,请选19:t");for(;)gets(s);cn=atoi(s);if(cn<1|cn>9) printf("nt输入错误,重选19:");else break;return cn;/*结束运行*void quit(void)char str5;if(savedTag=1)printf("是否保存原来的记录?(y/n)");gets(str);if(str0!='n' && str0!='N')saveRecords();free(records);exit(0); 1.总体设计:本设计有4个C文件(14个函数)和一个头文件组成,每个C文件都代表着某种特定功能,他们的关系如表12-1所示。 程序包含头文件的存、取过程,其功能就是按输入顺序建立记录。如果原来没有记录文件,可以重新建立一个文件;如果已经有记录,可以先把文件内容读入,然后把新记录追加到原来记录的尾部;也可以单独建立新文件,以后再使用读取文件的方法拼装。 表121 文件及函数组成源 文 件函数名或其他成分功 能student.cmain总控函数menu_select菜单选择handle_menu菜单处理quit结束运行add_disp.cshowtable输出表头addRecord在结尾追加信息display显示信息que_remv_modi.cremoveRecord删除指定记录findRecord查找指定的记录queryInfo查询指定的学生信息copyRecord复制记录modifRecord修改指定学生的信息sav_load.csave文件存储load文件读取student.h常数提供常数结构申明学生成绩结构库函数及函数原型申明引用库函数及函数由上述功能分析可以看到改程序的全貌。因为它有并列选择,所可以用选择菜单方便地实现。这个菜单具有8项,用switch语句可以实现这些选择。所以用简洁的伪码对它们进行选择,因为并不复杂,所以这里不自在赘述。2.函数具体设计为一些函数设计两个返回值以区分其执行结果是否正确。每个学生信息资料用一个StnInfo结构来保存,用StuInfo数组的全局变量records来保存一批学生的信息资料。宏定义INTIAL_SIZE表示数组初始大小,当已分配的数组大小不够用时,敬爱那个增加数组大小,INCR_SIZE为每次增加的大小。全局变量numStus 表示数组中记录的学生数,arraySize是为数组分配的空间大小。全局变量savedTag是信息是否保存的标志,当数组内容被保存只文件后,设为以保存状态,当数组内容被修改之后,设为“未保存”状态。1) .文件存储操作函数函数原型:int savedRecord(void)功 能:将及录存入默认文件 stu_info 或者指定文件。参 数:void。返 回 值:成功0,失败-1。工作方式:数组records被保存至指定文件。要 求:报告是否有记录可保存、是否能正常建立或打开文件、根据要求执行存入操作并报告存入记录的条数。2) .文件读取操作函数函数原型:int loadRecords(void)文件是否存在输入文件新信息导入成功是否创建文件退 出是否保存?保存成功退 出开始结束功 能:将默认文件stu_info 或者指定文件里的记录存入内存。参 数:void。返 回 值:成功0,失败-1。工作方式:records 为从指定文件中读取出记录。要 求:报告是否有记录可存、是否能正常打开文件、是否覆盖已有记录以及读取记录的条数。3) .显示所有学生信息函数函数原型:void display(void)功 能:显示内存里的记录信息。参 数:void。返 回 值:void。工作方式:从头文件开始逐个显示记录内容。要 求:报告是否有记录及记录条数和内容。4) .增加信息函数函数原型:void addRecord(void)功 能:增加记录。参 数:void。返 回 值:void。工作方式:从尾部开始逐个追加记录。要 求:将新记录追加在记录尾部,并对记录进行计数。5) .输出表头函数函数原型:void showTable(void)功 能:输出表头信息。 改表头里面含有学生学号,姓名,性别,及各学科名称,总分,平均分,这样以后每一次要输出学生信息是直接就可以用此函数,减少程序的代码,是程序简单化。参 数:void。返 回 值:void。工作方式:输出头一行表头信息。要 求:输出一行表头信息。6) .删除记录函数函数原型:void removerecord(void)功 能:删除内存数组中指定记录。 如果有的学生信息发生改变,你可以丢它进行删除,删除之前,你必须找到你要修改学生的记录,你可以根据姓名,学号超找改学生的信息,找到之后,若要删除,就对它进行删除。参 数:void。返 回 值:void。工作方式:根据给定的关键字,查找符合的记录并删除之。输入是否存在输入学生新信息修改成功退 出输入要修改的学生学号开始结束要 求:将后面的记录前移,同时改变名次并给出相关信息。7) .查找指定记录函数函数原型:void findRecord(char*,int,int)功 能:查找指定记录。参 数:char *target:欲查找记录的某一项与target相同。 int targetType:表明通过哪一项来查找,0为学号, 1为姓名,2为名次。 int from:从第from个记录开始找。返 回 值:int(找到的记录序号),若找不到则返回-1。工作方式:根据给定的关键字,查找符合记录的序号。开始N输入是否合法退 出Y按学号查询?输入学号按姓名查询输入姓名显示结果显示结果结束要 求:找不到则返回-1。8) .查找指定学生信息函数函数原型:void queryInfo(void)功 能:将一个文件的内容追加到另一个文件的尾部。参 数:void。返 回 值:void。工作方式:可以按照学号、姓名或名次来查询。要 求:打印查询到得学生信息或给出相关信息。9) .记录复制函数函数原型:void copyRecord(stuInfo*, stuInfo*)功 能:将src指向的一条记录复制给dest指向的记录。参 数:StuInfo* src为源记录StuInfo* dest为目的记录。返 回 值:void。工作方式:将源记录逐条复制到目的记录。要 求:正确复制字符串。10) .修改指定学生信息函数函数原型:void modifyRecord(void)功 能:找到指定记录并修改。如果有的学生信息发生改变,你可以丢它进行修改,修改之前,你必须找到你要修改学生的记录,你可以根据姓名,学号超找改学生的信息,找到之后,若要修改,就对它进行修改。参 数:void。返 回 值:void。工作方式:可以按照学号、姓名活名次找到要修改的记录,确认后方可修改。要 求:同时需要调整名次。11) .菜单处理函数函数函数原型:void handle_menu(void)功 能:处理选择的菜单命令。参 数:void。返 回 值:void。工作方式:根据命令,调用相应函数。要 求:给出结束信息。12) .菜单选择函数函数原型:void menu_select(void)功 能:接受用户选择代码。参 数:void。返 回 值:int。工作方式:返回命令代码整数值。要 求:只允许选择规定键,若果输入不符合要求,则提醒用户重新输入。13) .结束程序运行函数函数原型:void quit(ADDR*)功 能:结束程序运行。参 数:void。返 回 值:void。工作方式:根据要求决定在退出前是否将修改的记录存入文件。要 求:结束运行之前,询问是否丢修改的记录进行存储。14) 排序函数函数原型:sortInfo(void)功 能:对学生的总进行排序,可以按照升序,降序,对学生成绩或学号进行准确的排名。参 数:void。返 回 值:void。工作方式:对学生进行排序,可以根据需要,对学生的学号或者成绩进行升序或者降序。你通过选择17中的选项来满足你的需求。要 求:升序或者降序。15) .主函数函数原型:void main(void)功 能:控制程序。参 数:void。返 回 值:void。要 求:管理菜单命令并