学生管理系统 C语言.docx
- 文档编号:5759459
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:32
- 大小:258.79KB
学生管理系统 C语言.docx
《学生管理系统 C语言.docx》由会员分享,可在线阅读,更多相关《学生管理系统 C语言.docx(32页珍藏版)》请在冰豆网上搜索。
学生管理系统C语言
C语言程序设计
课程设计报告
设计题目:
学生成绩管理系统
学号201230283151
班级12级电信信息三班
姓名王自钊
完成方式:
(单选)
自我评分:
(单选)
○独立完成
○优秀
●参考他人工作的基础上完成
●良好
○在他人的帮助下完成
○中等
○完整拷贝他人成果
○及格
○不及格
2013年5月18日
设计任务:
C语言课程设计任务书3
题目:
学生成绩管理系统
功能:
学生成绩管理系统,每个学生是一个记录,包括学号,姓名,性别,3门课程成绩。
系统要求实现以下功能:
1、信息录入:
录入学生成绩信息(包括学生学号、姓名、各门课程的成绩等);
2、信息查询:
输入学号,查询学生各门课程的成绩,并显示。
3、排序:
按各门课程的成绩平均分进行排序,并显示。
4、信息删除与修改——输入学号,删除该学生的成绩信息。
分步实施:
1、初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数。
2、建立一个文件,将每位学生的信息写入文件中并能显示于屏幕上。
3、完成上述信息查询(学生学号、姓名等)、排序、信息删除与修改功能。
要求:
1、用C语言实现程序设计;
2、利用结构体数组实现学生信息的数据结构设计;
3、系统的各个功能模块要求用函数的形式实现;
4、界面友好(良好的人机交互),程序加必要的注释。
一、总体设计
1.程序总体设计
1)主操作界面与次级操作界面
2)学生信息成绩录入功能
3)学生信息成绩查询功能
4)学生信息成绩修改模块
5)学生信息成绩删除功能
6)输出系统内全部信息功能
7)各科平均分排序功能
2.数据结构
typedeffloatElemType;
typedefstructNodeType/*本程序使用的结构体,具体成员在下面注释*/
{
unsignedlongNum;//学号
charname[15];//学生姓名
ElemTypecourse[3];//学生三门科目的成绩
ElemTypeaverage;//学生三门科目成绩平均分
charSex[3];//学生性别
structNodeType*next;//指向下一个结构体的指针
}NodeType,*LinkList;//结点和指针类型
3.函数原型声明的说明
voidMakeNode(LinkList&q);//分配由L指向的元素为e,后继为空的结点
voidInitlist(List&L);//初始化链表
voidInsert(List&L,LinkListq,LinkLists);//在指针q所指元素后插入s指针所指向的元素
voidClear(List&L);//清空链表(系统重置)
voidAppend(List&L,LinkLists);//在线性链表尾部插入一个结点s
voidReadin(List&L);//从文件中读入数据
voidSearchStu(ListL);//按学号查找信息并显示
voidPrintfall(ListL);//输出所有学生的成绩信息到屏幕
voidInsertstu(List&L);//插入一个学生的成绩信息
voidFwriteStu(ListL);//保存学生数据信息
voidChange(ListL,LinkListp);//修改学生信息
voidChangeclear(LinkListp);//修改操作中的清屏
voidStucopy(LinkListp,LinkListq);//结点复制
voidAlter(ListL);//按学号修改信息
voidDelete(ListL);//按学号删除信息
voidrank(ListL);//各科平均分排序
voidsysclear();//操作完成后清屏并返回主菜单
voidtable();//输出信息时的表头
intLocate(ListL,unsignedlonge,LinkList&p);//按学号定位
4.流程图
二、详细设计
输出p指向结点内所有信息到屏幕
调用sysclear()清屏返回主菜单
是否重新输入学号e?
重新输入e
p=p.next
p.num==e?
p.next==NULL?
从主菜单接受指令
输入学号e,定义结点指针p,p=L.head
1.查找
voidSearchStu(ListL)
N
N
YY
N
输出p指向结点内所有信息到屏幕
调用sysclear()清屏并返回主菜单
是否重新输入学号e?
重新输入e
“是否确认删除YorN”
从主菜单接受指令
输入学号e,定义结点指针p,q,q=L.head,p=q.next
q=q.next
p=q.next
p.num==e?
p.next==NULL?
p->next=q->next;
L.len--;
free(q);FwriteStu(L);
调用sysclear()清屏返回主菜单
2.删除voidDelete(ListL);
N
N
YY
Y
N
N
Y
从主菜单接受指令
3.修改
输入学号e,定义结点指针p,q,q=L.head
q=q.next
p.next==NULL?
p.num==e?
重新输入e
是否重新输入学号e?
输出p指向结点内所有信息到屏幕
“是否确认要修改YorN”
调用sysclear()清屏并返回主菜单
Stucopy(p,q);将p数据复制到q中
调用Change(L,p)
c==0
Stucopy(q,p);
free(q);FwriteStu(L);
free(q);FwriteStu(L);
保存修改?
返回主菜单
scanf("%d",&p->Num)
scanf("%s",&p->name)
scanf("%f",&p->course[0])
scanf("%s",&p->Sex)
scanf("%f",&p->course[1])
scanf("%f",&p->course[2])
c==0?
c==1?
c==2?
c==3?
c==4?
c==5?
c==6?
Inputc
intc//操作数
chark//操作字符
显示修改菜单
三、测试及调试
1.测试中出现的部分问题及解决方法
1.1计算各门科目平均分并排序输出时发生错误
原语句如下:
for(p=L.head;i>0;i--,p=p->next)
{
sum1=p->course[0]+sum1;
sum2=p->course[1]+sum2;
sum3=p->course[2]+sum3;
}
测试方案:
在计算和的同时将结点中各成绩数据输出到屏幕
测试语句:
for(p=L.head;i>0;i--,p=p->next)
{printf("%.1f%.1f%.1f\n",,p->course[0],p->course[1],p->course[2]);
sum1=p->course[0]+sum1;
sum2=p->course[1]+sum2;
sum3=p->course[2]+sum3;}
经过排查,发现循环开始时p直接指向头结点,而头结点本身只作为链表地址指示,不储存学社成绩信息,其中数据为随机数,尤其引发逻辑错误。
解决方案:
直接将结点指针p指向头结点的下一个结点.
修改后语句如下:
for(p=L.head->next;i>0;i--,p=p->next)
{sum1=p->course[0]+sum1;
sum2=p->course[1]+sum2;
sum3=p->course[2]+sum3;}
修改后输出正确结果:
1.2由语法错误引起在执行修改和删除功能时程序停止运作
原错误语句:
printf("\n请输入相应的操作:
");scanf("%d",c);
虽然只是缺少了一个符号,但却引起了整个程序的奔溃。
解决方案:
上网搜索相似错误案例,得知原因之一可能为变量赋值时出错而引起,随检查相关函数的变量赋值语句,成功发现错误,加上“&”后程序运作正常。
1.3修改后选择“不保存修改”,但此次运行中显示信息时为修改后信息
错误原因:
在最初设计函数时将“保存修改”的执行语句设计为FwriteStu(ListL),即修改后学生数据信息读入文件中,而“不保存修改”的执行语句为空,即只是不将修改后的信息读入文件中,这样,在第二次运行程序时将读入没有修改的信息,但是,若在此次运行中输出这些信息到屏幕时,将输出已修改的信息。
解决方案:
在进入修改操作时在定义一个结点指针q,并为其开辟空间,用于储存被修改结点p的原信息。
相关源代码:
LinkListq;//保存原信息的结点
q=(LinkList)malloc(sizeof(NodeType));
Stucopy(p,q);//将p的数据拷贝到q中
在文件末尾改为:
printf("\n!
!
!
你将要退出操作,是否确认修改?
YorN!
!
!
\n");
getchar();
scanf("%c",&k);
if(k=='Y')
FwriteStu(L);//输出成绩信息到文件中
else
Stucopy(q,p);//将q的数据拷贝到p中,即恢复数据
free(q);
2.主要程序运行结果
1.开始运行(主菜单)
2.学生信息录入
3.学生信息查询
输出信息界面
4.修改
查询确认界面
修改界面
当前信息显示与修改同步
5.各科平均分排序
6.删除
7.输出全部学生信息
四、小结
这是我第一次独自编写一个较复杂的程序,在刚开始时本想完全独立完成,但是由于目前能力有限和经验不足,进度缓慢,而且错漏百出,遂找来了一个例子作为参考,但主要核心代码都有自己编写,完成后程序与参考作品有较大差异,个人认为自己的程序在某些方面上优于参考作品,例如,参考作品没有清屏功能,每次操作的输出都堆加到屏幕上,有累赘感,而我的作品除了信息录入功能外每个操作的结果都会独立于主菜单之外显示,更加人性化,但与参考作品相比我的不足也不少,例如,没有保护设置,任何人都能进入系统中进行操作,缺乏安全性。
本来此次作业我能做得更好,但是由于自己没有合理分配时间,导致由于此次大作业的时间并不多,所以程序的功能只是在满足基本要求添加了另外一个功能,虽然本来设计了不少附加功能但都没有时间成功实现,例如,按学生名字查询(并修改或删除)成绩信息,考虑到姓名相同而导致无法全部输出的可能性此功能并非必需,学号虽然原则上不会重复但当学号输入错误时,例如由于输入字符导致学号为负值,无法通过学号进行修改和删除,只能通过系统重置来消除错误。
在程序测试和调试中出现的错误也令我有不少收获,例如前面提到的“由语法错误引起在执行修改和删除功能时程序停止运作”,一个小小的“&”符号的缺失就能让一个五百多行的程序崩溃,让我认识到什么叫做“细节决定成败”,让我认识到“从小事做起”确实是很有道理的,认识到从今往后要做事要脚踏实地。
本次作业也让我认识到了对Officeword办公软件的熟练运用的重要性,作业报告中要求我们画流程图,由于对word2007中形状插入功能不熟悉,导致在此花费了不少时间,同时我也认识到word2007的功能或许完善但操作起来却不够人性化,毕竟世界上没有完美的程序,这着驱使人们去创造更好的程序。
看到自己付出汗水完成的程序正常的运行那种感觉非常不错,看到自己的付出有相应的回报,确实令人欣慰。
附件:
主要源程序代码
头文件:
#include
#include
#include"colorConsole.h"
#include
#include
#include
#include
#include
#defineun"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
typedeffloatElemType;
typedefstructNodeType
{
unsignedlongNum;//学号
charname[15];//学生姓名
ElemTypecourse[3];//学生成绩
ElemTypeaverage;//学生各科平均分
charSex[3];//学生性别
structNodeType*next;//指向下一个结构体的指针
}NodeType,*LinkList;//结点和指针类型
typedefstruct
{
LinkListhead,tail;//链表的头尾指针
intlen;//记录学生是个数
}List;//链表类型
-----------------------------------主函数-------------------------------------
#include"头文件啊喵.h"
voidmain()
{
ListL;
Initlist(L);
Readin(L);
charc='a';
inti;//操作数
system("title学生成绩管理系统★");
system("color9a");
HANDLEhandle;
handle=initiate();
WORDwColors[1];
wColors[0]=FOREGROUND_RED|FOREGROUND_INTENSITY|BACKGROUND_BLUE;
textout(handle,16,2,wColors,1,"〓〓〓〓★★★★学生成绩管理系统★★★★〓〓〓〓");
textout(handle,20,5,wColors,1,"〓〓〓〓1.录入学生成绩信息〓〓〓〓");
textout(handle,20,7,wColors,1,"〓〓〓〓2.查寻学生成绩信息〓〓〓〓");
textout(handle,20,9,wColors,1,"〓〓〓〓3.修改学生成绩信息〓〓〓〓");
textout(handle,20,11,wColors,1,"〓〓〓〓4.各科成绩平均分排序〓〓〓〓");
textout(handle,20,13,wColors,1,"〓〓〓〓5.删除学生成绩信息〓〓〓〓");
textout(handle,20,15,wColors,1,"〓〓〓〓6.显示所有学生成绩〓〓〓〓");
textout(handle,20,17,wColors,1,"〓〓〓〓0.退出成绩管理系统〓〓〓〓");
printf(un);
printf("请输入你想要进行操作对应的数字:
");
scanf("%d",&i);
while(i!
=0)
{switch(i)
{case1:
Insertstu(L);
FwriteStu(L);
sysclear();
break;
case2:
SearchStu(L);
sysclear();
break;
case3:
Alter(L);
sysclear();
break;
case4:
rank(L);
sysclear();
break;
case5:
Delete(L);
sysclear();
break;
case6:
Printfall(L);
sysclear();
break;
default:
printf("!
!
!
!
输入指令错误!
!
!
!
");
sysclear();
break;
}
printf("请输入下一步操作指示:
");
scanf("%d",&i);
}
if(i=0)
Clear(L);
printf("您已安全退出程序\n");
}
-------------------------------------------各种函数-------------------------------------------
voidMakeNode(LinkList&q)//分配由L指向的元素为e,后继为空的结点
{q=(LinkList)malloc(sizeof(NodeType));
if(!
q)
{printf("ERROR\n");}
else
{printf("\n学号:
");
scanf("%d",&q->Num);
printf("\n姓名:
");
scanf("%s",&q->name);
getchar();
printf("\n性别:
");
scanf("%s",&q->Sex);
printf("\n科目1成绩:
");
scanf("%f",&q->course[0]);
printf("\n科目2成绩:
");
scanf("%f",&q->course[1]);
printf("\n科目3成绩:
");
scanf("%f",&q->course[2]);
q->average=(q->course[1]+q->course[2]+q->course[0])/3.00;//计算平均分//
q->next=NULL;}
}
voidStucopy(LinkListp,LinkListq)//结点复制
{
q->Num=p->Num;
strcpy(q->name,p->name);
strcpy(q->Sex,p->Sex);
q->course[0]=p->course[0];
q->course[1]=p->course[1];
q->course[2]=p->course[2];
q->next=p->next;
}
voidInitlist(List&L)//初始化链表
{
L.tail=L.head=(LinkList)malloc(sizeof(NodeType));
L.head->next=L.tail->next=NULL;
L.len=0;
}
voidInsert(List&L,LinkListq,LinkLists)//在指针q所指元素后插入s指针所指向的元素
{
if(L.head&&q&&s)
{
s->next=q->next;
q->next=s;
if(L.tail==q)
{L.tail=s;}//如果q刚好等于尾指针,则将尾指针移动到最后一个元素的指针s处//
L.len++;
printf("已录入\n");
}
}
voidClear(List&L)//清空链表,也是系统重置
{
LinkLists,m;
s=L.head->next;
while(s!
=NULL)
{
m=s->next;
free(s);
s=m;
}
L.tail=L.head;
L.head->next=NULL;
L.tail->next=NULL;
L.len=0;
printf("OK\n");
}
voidAppend(List&L,LinkLists)//在线性链表尾部插入一个结点s
{
if(L.head&&s)
{if(L.tail!
=L.head)L.tail->next=s;//头结点不等于尾结点,在后面插入s//
elseL.head->next=s;//头结点等于尾结点,在头结点后插入s//
L.tail=s;
L.len++;//把尾指针移动到线性链表最后一个元素s,链表长度加1}
}
intLocate(ListL,unsignedlonge,LinkList&p)//按学号定位
{
LinkListpre;
if(L.head)
{
pre=L.head;
p=pre->next;//pre指向*p的前驱,p指向第一个元素结点
while(p&&p->Num {pre=p;p=p->next;} if(p&&p->Num==e) {return1;}//带回与e相等的元素的结点 else {p=pre; return1; }//带回第一个比e大的元素的结点 } else {return0;} } voidReadin(List&L)//从文件中读入数据 { FILE*stu; LinkListp; if((stu=fopen("学生成绩信息.txt","r+"))==NULL) printf("抱歉! 读入失败\n"); while(! feof(stu)) { p=(LinkList)malloc(sizeof(NodeType));p->next=NULL; fscanf(stu,"%d%s%s%f%f%f%f\n",&p->Num,&p->name,&p->Sex,&p->course[0],&p->course[1],&p->course[2],&p->average); Append(L,p); } fclose(stu); } voidFwriteStu(ListL)//保存学生数据信息 { LinkListp; FILE*stu; charfilename[20]="学生成绩信息.txt"; if((stu=fopen(filename,"w+"))==NULL) {printf("文件创建失败\n"); exit(0); } fseek(stu,0,0); for(p=L.head->next;p! =NULL;p=p->next) { fprintf(stu,"%d%s%s%.2f%.2f%.2f%.2f\n",p->Num,p->name,p->Sex,p->course[0],p->course[1],p->course[2],p->average); } fclose(stu); } voidInsertstu(List&L)//插入一个学生的成绩信息 { LinkListp,q; MakeNode(p); if(Locate(L,p->Num,q)) {Insert(L,q,p);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 学生管理系统 C语言 学生 管理 系统 语言