还剩20页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
C语言课程设计报告实验报告专业:班级:姓名:学号:题目学生成绩管理程序该程序是一个简单的学生成绩管理程序.它可以录入多个同学的基本情况:学号、姓名、数学,英语,C语言分数同时还可以输出学生的平均,分总分并且能够将所有学生的基本情况和各课的成绩作适当修改和删除以及统计与排名,同时能够将每个学生的成绩输出.一数据结构设计及用法说明在整个程序中采用了多种数据结构,包括有基本类型中的1整型int、char、long2浮点型double、float3导出类型指针、数组、结构(struct),链表程序中的几个主要的结构void__in{intmm;for;1;{printf请输入__\n;scanf%dmm;ifmm==123break;elseprintf__错误;请重输入__\n;}Linkl;/*定义链表*/FILE*fp;/*文件指针*/intselect;/*保存选择结果变量*/charch;/*保存yYnN*/intcount=0;/*保存文件中的记录条数(或结点个数)*/Node*p*r;/*定义记录指针变量*/l=Node*__llocsizeofNode;if!l{printf\n内存分配失败;/*如没有申请到,打印提示信息*/return;/*返回主界面*/}l-next=NULL;r=l;fp=fopenC:\\studentab+;/*以追加方式打开一个二进制文件,可读可写,若此文件不存在,会创建此文件*/iffp==NULL{printf\n=====无法打开文件!\n;exit0;}while!feoffp{p=Node*__llocsizeofNode;if!p{printfmemory__llocfailure!\n;/*没有申请成功*/exit0;/*退出*/}iffreadpsizeofNode1fp==1/*一次从文件中读取一条学生成绩记录*/{p-next=NULL;r-next=p;r=p;/*r指针向后移一个位置*/count++;}}fclosefp;/*关闭文件*/printf\n=====打开文件成功,共记录的数目:%d.\ncount;menu;while1{systemcls;menu;p=r;printf\n请输入您的选择0~9:;/*显示提示信息*/scanf%dselect;ifselect==0{ifs__eflag==1/*若对链表的数据有修改且未进行存盘操作,则此标志为1*/{getchar;printf\n=====是否保存修改记录文件y/n:;scanf%cch;ifch==y||ch==YS__el;}printf=====谢谢使用!;getchar;break;}switchselect{case1:Addl;break;/*增加学生记录*/case2:Dell;break;/*删除学生记录*/case3:Qurl;break;/*查询学生记录*/case4:Modifyl;break;/*修改学生记录*/case5:Insertl;break;/*插入学生记录*/case6:Tongjil;break;/*统计学生记录*/case7:Sortl;break;/*排序学生记录*/case8:S__el;break;/*保存学生记录*/case9:{systemcls;Displ;printf按任何键返回;chara;scanf%da;break;}/*显示学生记录*/default:Wrong;getchar;break;/*按键有误,必须为数值0-9*/}}}程序中建立了多个函数分别来完成每个所要求的功能读文件和写文件函数,建链表函数,插入、修改和删除函数,排序、统计和输出函数.程序利用各个函数来完成前面要求所需要的功能二程序调用图三功能菜单#***************************菜单**************************;*1输入成绩*2删除成绩*3查询成绩*4____*5插入成绩*6统计成绩*7成绩排序*8保存成绩*9显示成绩*0退出系统#*********************************************************四.实验结果;(见程序运行)五体会做完这个c语言程序设计的作业我学会了很多新知识,对c语言有了更进一步的了解.开始时我想用结构数组来做这个程序但后来我发现用做它修改数据和读取数据都显得很方便.于是相比较之下我便选择了链表.编程时会遇到一些困难最令人头疼的莫过于程序运行时出错了.有时哪怕是一些很小的错误经常能导致难以预料到的后果因此编程时我尽量做到一丝不苟不敢有丝毫疏忽.通过这次c语言编程的练习我的编程水平有了进一步的提高同时也使我对编程有了一个更清醒的了解和认识.六,程序//__123#includestdio.h/*标准输入输出函数库*/#includestdlib.h/*标准函数库*/#includestring.h/*字符串函数库*/#includeconio.h/*屏幕操作函数库*/#defineHEADER1---------------------------------学生成绩----------------------------------\n#defineHEADER2|学号|姓名|C语言|数学|英语|总分|平均分|名次|\n#defineHEADER3|---------------|---------------|-----|----|-----|--------|--------|-----|#defineFOR__T|%-10s|%-15s|%4d|%4d|%4d|%4d|%.2f|%4d|\n#defineDATAp-data.nump-data.namep-data.egradep-data.mgradep-data.cgradep-data.totalp-data.__ep-data.min__i#defineEND---------------------------------------------------------------------\nints__eflag=0;/*是否需要存盘的标志变量*//*定义与学生有关的数据结构*/typedefstructstudent/*标记为student*/{charnum
[10];/*学号*/charname
[15];/*姓名*/intcgrade;/*C语言成绩*/intmgrade;/*数学成绩*/integrade;/*英语成绩*/inttotal;/*总分*/float__e;/*平均分*/intmin__i;/*名次*/};/*定义每条记录或结点的数据结构,标记为node*/typedefstructnode{structstudentdata;/*数据域*/structnode*next;/*指针域*/}Node*Link;/*Node为node类型的结构变量,*Link为node类型的指针变量*/voidmenu/*主菜单*/{systemcls;/*调用DOS命令,清屏.与clrscr功能相同*/cprintf学生成绩管理系统\n;cprintf#***************************菜单**************************#\n;cprintf*1输入成绩*2删除成绩*\n;cprintf*3查询成绩*4____*\n;cprintf*5插入成绩*6统计成绩*\n;cprintf*7成绩排序*8保存成绩*\n;cprintf*9显示成绩*0退出系统*\n;cprintf#*********************************************************#\n;/*cprintf送格式化输出至文本窗口屏幕中*/}voidprintheader/*格式化输出表头*/{printfHEADER1;printfHEADER2;printfHEADER3;}voidprintdataNode*pp/*格式化输出表中数据*/{Node*p;p=pp;printfFOR__TDATA;}voidWrong/*输出按键错误信息*/{printf\n\n\n\n\n***********输入有错!按任意键继续!**********\n;getchar;}voidNofind/*输出未查找此学生的信息*/{printf\n=====没有找到这名学生!\n;}voidDispLinkl/*显示单链表l中存储的学生记录,内容为student结构中定义的内容*/{Node*p;p=l-next;/*l存储的是单链表中头结点的指针,该头结点没有存储学生信息,指针域指向的后继结点才有学生信息*/if!p/*p==NULLNUll在stdlib中定义为0*/{printf\n=====没有学生记录!\n;getchar;return;}printf\n\n;printheader;/*输出表格头部*/whilep/*逐条输出链表中存储的学生信息*/{printdatap;p=p-next;/*__直下一个结点*/printfHEADER3;}getchar;}/*************************************************************作用用于定位链表中符合要求的节点,并返回指向该节点的指针参数findmess[]保存要查找的具体内容;nameornum[]保存按什么查找;在单链表l中查找;**************************************************************/Node*LocateLinklcharfindmess[]charnameornum[]{Node*r;ifstrcmpnameornumnum==0/*按学号查询*/{r=l-next;whiler{ifstrcmpr-data.numfindmess==0/*若找到findmess值的学号*/returnr;r=r-next;}}elseifstrcmpnameornumname==0/*按姓名查询*/{r=l-next;whiler{ifstrcmpr-data.namefindmess==0/*若找到findmess值的学生姓名*/returnr;r=r-next;}}return0;/*若未找到,返回一个空指针*/}/*输入字符串,并进行长度验证长度lens*/voidstringinputchar*tintlenschar*noti__{charn
[255];do{printfnoti__;/*显示提示信息*/scanf%sn;/*输入字符串*/ifstrlennlensprintf\n超过所需长度!\n;/*进行长度校验,超过lens值重新输入*/}whilestrlennlens;strcpytn;/*将输入的字符串拷贝到字符串t中*/}/*输入分数,0=分数=100*/intnumberinputchar*noti__{intt=0;do{printfnoti__;/*显示提示信息*/scanf%dt;/*输入分数*/ift100||t0printf\n评分必须在
[0100]!\n;/*进行分数校验*/}whilet100||t0;returnt;}/*增加学生记录*/voidAddLinkl{Node*p*r*s;/*实现添加操作的临时的结构体指针变量*/charchflag=0num
[10];r=l;s=l-next;systemcls;Displ;/*先打印出已有的学生信息*/whiler-next!=NULLr=r-next;/*将指针移至于链表最末尾,准备添加记录*/while1/*一次可输入多条记录,直至输入学号为0的记录结点添加操作*/{while1/*输入学号,保证该学号没有被使用,若输入学号为0,则退出添加记录操作*/{stringinputnum10输入号码(按0返回菜单):;/*格式化输入学号并检验*/flag=0;ifstrcmpnum0==0/*输入为0,则退出添加操作,返回主界面*/{return;}s=l-next;whiles/*查询该学号是否已经存在,若存在则要求重新输入一个未被占用的学号*/{ifstrcmps-data.numnum==0{flag=1;break;}s=s-next;}ifflag==1/*提示用户是否重新输入*/{getchar;printf=====人数%s是不存在的,再试一次?(y/n)num;scanf%cch;ifch==y||ch==Ycontinue;elsereturn;}else{break;}}p=Node*__llocsizeofNode;/*申请内存空间*/if!p{printf\n内存分配失败;/*如没有申请到,打印提示信息*/return;/*返回主界面*/}strcpyp-data.numnum;/*将字符串num拷贝到p-data.num中*/stringinputp-data.name15Name:;p-data.cgrade=numberinputC语言[0-100]:;/*输入并检验分数,分数必须在0-100之间*/p-data.mgrade=numberinput数学Score[0-100]:;/*输入并检验分数,分数必须在0-100之间*/p-data.egrade=numberinput英语Score[0-100]:;/*输入并检验分数,分数必须在0-100之间*/p-data.total=p-data.egrade+p-data.cgrade+p-data.mgrade;/*计算总分*/p-data.__e=floatp-data.total/3;/*计算平均分*/p-data.min__i=0;p-next=NULL;/*表明这是链表的尾部结点*/r-next=p;/*将新建的结点加入链表尾部中*/r=p;s__eflag=1;}return;}voidQurLinkl/*按学号或姓名,查询学生记录*/{intselect;/*1:按学号查,2按姓名查,其他返回主界面(菜单)*/charsearchinput
[20];/*保存用户输入的查询内容*/Node*p;if!l-next/*若链表为空*/{systemcls;printf\n=====没有学生记录!\n;getchar;return;}systemcls;printf\n=====1按学号搜寻=====2按名称搜索\n;printfpleasechoi__
[12]:;scanf%dselect;ifselect==1/*按学号查询*/{stringinputsearchinput10输入现有的学生学号:;p=Locatelsearchinputnum;/*在l中查找学号为searchinput值的节点,并返回节点的指针*/ifp/*若p!=NULL*/{printheader;printdatap;printfEND;printf按任意键返回;getchar;}elseNofind;getchar;}elseifselect==2/*按姓名查询*/{stringinputsearchinput15输入现有的学生姓名:;p=Locatelsearchinputname;ifp{printheader;printdatap;printfEND;printf按任意键返回;getchar;}elseNofind;getchar;}elseWrong;getchar;}/*删除学生记录先找到保存该学生记录的节点,然后删除该节点*/voidDelLinkl{intsel;Node*p*r;charfindmess
[20];if!l-next{systemcls;printf\n=====没有该学生的记录\n;getchar;return;}systemcls;Displ;printf\n=====1按学号删除=====2按姓名删除\n;printf请选择
[12]:;scanf%dsel;ifsel==1{stringinputfindmess10输入现有的学生学号:;p=Locatelfindmessnum;ifp/*p!=NULL*/{r=l;whiler-next!=pr=r-next;r-next=p-next;/*将p所指节点从链表中去除*/freep;/*释放内存空间*/printf\n=====删除成功!\n;getchar;s__eflag=1;}elseNofind;getchar;}elseifsel==2/*先按姓名查询到该记录所在的节点*/{stringinputfindmess15输入现有的学生姓名;p=Locatelfindmessname;ifp{r=l;whiler-next!=pr=r-next;r-next=p-next;freep;printf\n=====删除成功!\n;getchar;s__eflag=1;}elseNofind;getchar;}elseWrong;getchar;}/*修改学生记录先按输入的学号查询到该记录,然后提示用户修改学号之外的值,学号不能修改*/voidModifyLinkl{Node*p;charfindmess
[20];if!l-next{systemcls;printf\n=====没有该学生记录!\n;getchar;return;}systemcls;printf修改学生记录;Displ;stringinputfindmess10inputtheexistingstudentnumber:;/*输入并检验该学号*/p=Locatelfindmessnum;/*查询到该节点*/ifp/*若p!=NULL表明已经找到该节点*/{printfNumber:%s\np-data.num;printfName:%sp-data.name;stringinputp-data.name15输入新姓名:;printfC语言分数:%dp-data.cgrade;p-data.cgrade=numberinputC语言分数[0-100]:;printf数学分数:%dp-data.mgrade;p-data.mgrade=numberinput数学分数[0-100]:;printf英语分数:%dp-data.egrade;p-data.egrade=numberinput英语分数[0-100]:;p-data.total=p-data.egrade+p-data.cgrade+p-data.mgrade;p-data.__e=floatp-data.total/3;p-data.min__i=0;printf\n=====修改成功!\n;Displ;s__eflag=1;}elseNofind;getchar;}/*插入记录:按学号查询到要插入的节点的位置,然后在该学号之后插入一个新节点*/voidInsertLinkl{Linkpvnewinfo;/*p指向插入位置,newinfo指新插入记录*/charchnum
[10]s
[10];/*s[]保存插入点位置之前的学号num[]保存输入的新记录的学号*/intflag=0;v=l-next;systemcls;Displ;while1{stringinputs10请输入要输入号码插入的位置:;flag=0;v=l-next;whilev/*查询该学号是否存在,flag=1表示该学号存在*/{ifstrcmpv-data.nums==0{flag=1;break;}v=v-next;}ifflag==1break;/*若学号存在,则进行插入之前的新记录的输入操作*/else{getchar;printf\n=====学号%s是不存在的,再试一次吗?y/n:s;scanf%cch;ifch==y||ch==Y{continue;}else{return;}}}/*以下新记录的输入操作与Add相同*/stringinputnum10输入新学号:;v=l-next;whilev{ifstrcmpv-data.numnum==0{printf=====对不起,新的学号%s已存在!\nnum;printheader;printdatav;printf\n;getchar;return;}v=v-next;}newinfo=Node*__llocsizeofNode;if!newinfo{printf\nallocatememoryfailure;/*如没有申请到,打印提示信息*/return;/*返回主界面*/}strcpynewinfo-data.numnum;stringinputnewinfo-data.name15Name:;newinfo-data.cgrade=numberinputC语言分数[0-100]:;newinfo-data.mgrade=numberinput数学分数[0-100]:;newinfo-data.egrade=numberinput英语分数[0-100]:;newinfo-data.total=newinfo-data.egrade+newinfo-data.cgrade+newinfo-data.mgrade;newinfo-data.__e=floatnewinfo-data.total/3;newinfo-data.min__i=0;newinfo-next=NULL;s__eflag=1;/*在__in有对该全局变量的判断,若为1则进行存盘操作*//*将指针赋值给p因为l中的头节点的下一个节点才实际保存着学生的记录*/p=l-next;while1{ifstrcmpp-data.nums==0/*在链表中插入一个节点*/{newinfo-next=p-next;p-next=newinfo;break;}p=p-next;}Displ;printf\n\n;getchar;}/*统计该班的总分第一名和单科第一和各科不及格人数*/voidTongjiLinkl{Node*pm*pe*pc*pt;/*用于指向分数最高的节点*/Node*r=l-next;intcountc=0countm=0counte=0;/*保存三门成绩中不及格的人数*/if!r{systemcls;printf\n=====没有学生记录!\n;getchar;return;}systemcls;Displ;pm=pe=pc=pt=r;whiler{ifr-data.cgrade60countc++;ifr-data.mgrade60countm++;ifr-data.egrade60counte++;ifr-data.cgrade=pc-data.cgradepc=r;ifr-data.mgrade=pm-data.mgradepm=r;ifr-data.egrade=pe-data.egradepe=r;ifr-data.total=pt-data.totalpt=r;r=r-next;}printf\n------------------------------统计学生记录--------------------------------\n;printfC语言60:%d人\ncountc;printf数学60:%d人\ncountm;printf英语60:%d人\ncounte;printf-------------------------------------------------------------------------------\n;printf总分最高分:%stotoalscore:%d\npt-data.namept-data.total;printf英语最高分:%stotoalscore:%d\npe-data.namepe-data.egrade;printf数学最高分:%stotoalscore:%d\npm-data.namepm-data.mgrade;printfC语言最高分:%stotoalscore:%d\npc-data.namepc-data.cgrade;printf\n\npressanykeytoreturn;getchar;}/*利用插入排序法实现单链表的按总分字段的降序排序,从高到低*/voidSortLinkl{Linkll;Node*p*rr*s;inti=0;ifl-next==NULL{systemcls;printf\n=====没有学生记录!\n;getchar;return;}ll=Node*__llocsizeofNode;/*用于创建新的节点*/if!ll{printf\n内存分配失败;/*如没有申请到,打印提示信息*/return;/*返回主界面*/}ll-next=NULL;systemcls;Displ;/*显示排序前的所有学生记录*/p=l-next;whilep/*p!=NULL*/{s=Node*__llocsizeofNode;/*新建节点用于保存从原链表中取出的节点信息*/if!s/*s==NULL*/{printf\n内存分配失败;/*如没有申请到,打印提示信息*/return;/*返回主界面*/}s-data=p-data;/*填数据域*/s-next=NULL;/*指针域为空*/rr=ll;/*rr链表于存储插入单个节点后保持排序的链表,ll是这个链表的头指针每次从头开始查找插入位置*/whilerr-next!=NULLrr-next-data.total=p-data.total{rr=rr-next;}/*指针移至总分比p所指的节点的总分小的节点位置*/ifrr-next==NULL/*若新链表ll中的所有节点的总分值都比p-data.total大时,就将p所指节点加入链表尾部*/rr-next=s;else/*否则将该节点插入至第一个总分字段比它小的节点的前面*/{s-next=rr-next;rr-next=s;}p=p-next;/*原链表中的指针下移一个节点*/}l-next=ll-next;/*ll中存储是的已排序的链表的头指针*/p=l-next;/*已排好序的头指针赋给p,准备填写名次*/whilep!=NULL/*当p不为空时,进行下列操作*/{i++;/*结点序号*/p-data.min__i=i;/*将名次赋值*/p=p-next;/*指针后移*/}Displ;s__eflag=1;printf\n=====排序完成!\n;}/*数据存盘若用户没有专门进行此操作且对数据有修改,在退出系统时,会提示用户存盘*/voidS__eLinkl{FILE*fp;Node*p;intcount=0;fp=fopenc:\\studentwb;/*以只写方式打开二进制文件*/iffp==NULL/*打开文件失败*/{printf\n=====打开文件错误!\n;getchar;return;}p=l-next;whilep{iffwritepsizeofNode1fp==1/*每次写一条记录或一个节点信息至文件*/{p=p-next;count++;}else{break;}}ifcount0{getchar;printf\n\n\n\n\n=====保存文件的完整,总储存的记录数:%d\ncount;getchar;s__eflag=0;}else{systemcls;printf目前的链接是空的,没有学生记录保存!\n;getchar;}fclosefp;/*关闭此文件*/}void__in{intmm;for;1;{printf请输入__\n;scanf%dmm;ifmm==123break;elseprintf__错误;请重输入__\n;}Linkl;/*定义链表*/FILE*fp;/*文件指针*/intselect;/*保存选择结果变量*/charch;/*保存yYnN*/intcount=0;/*保存文件中的记录条数(或结点个数)*/Node*p*r;/*定义记录指针变量*/l=Node*__llocsizeofNode;if!l{printf\n内存分配失败;/*如没有申请到,打印提示信息*/return;/*返回主界面*/}l-next=NULL;r=l;fp=fopenC:\\studentab+;/*以追加方式打开一个二进制文件,可读可写,若此文件不存在,会创建此文件*/iffp==NULL{printf\n=====无法打开文件!\n;exit0;}while!feoffp{p=Node*__llocsizeofNode;if!p{printfmemory__llocfailure!\n;/*没有申请成功*/exit0;/*退出*/}iffreadpsizeofNode1fp==1/*一次从文件中读取一条学生成绩记录*/{p-next=NULL;r-next=p;r=p;/*r指针向后移一个位置*/count++;}}fclosefp;/*关闭文件*/printf\n=====打开文件成功,共记录的数目:%d.\ncount;menu;while1{systemcls;menu;p=r;printf\n请输入您的选择0~9:;/*显示提示信息*/scanf%dselect;ifselect==0{ifs__eflag==1/*若对链表的数据有修改且未进行存盘操作,则此标志为1*/{getchar;printf\n=====是否保存修改记录文件y/n:;scanf%cch;ifch==y||ch==YS__el;}printf=====谢谢使用!;getchar;break;}switchselect{case1:Addl;break;/*增加学生记录*/case2:Dell;break;/*删除学生记录*/case3:Qurl;break;/*查询学生记录*/case4:Modifyl;break;/*修改学生记录*/case5:Insertl;break;/*插入学生记录*/case6:Tongjil;break;/*统计学生记录*/case7:Sortl;break;/*排序学生记录*/case8:S__el;break;/*保存学生记录*/case9:{systemcls;Displ;printf按任何键返回;chara;scanf%da;break;}/*显示学生记录*/default:Wrong;getchar;break;/*按键有误,必须为数值0-9*/}}}主函数__in__验证函数功能8保存成绩
1.输入成绩2删除成绩5插入成绩3查询成绩4____6统计成绩7成绩排序0退出系统9显示成绩。