学生综合情况管理系统.docx
《学生综合情况管理系统.docx》由会员分享,可在线阅读,更多相关《学生综合情况管理系统.docx(42页珍藏版)》请在冰点文库上搜索。
![学生综合情况管理系统.docx](https://file1.bingdoc.com/fileroot1/2023-7/19/2aea6ca6-b80d-497c-b571-6f9b44b78a00/2aea6ca6-b80d-497c-b571-6f9b44b78a001.gif)
学生综合情况管理系统
淮北师范大学
《数据结构课程设计》任务书
设计题目:
学生综合情况管理系统
姓名:
吴创连
学号:
20111202052
学院:
计算机科学与技术(非师)
专业:
计算机科学与技术(非师)
辅导老师:
赵娟
2013.04.15
一,课程设计的目的:
数据结构课程设计是计算机专业重要的教学环节,
它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结
合起来,独立分析和解决实际问题的机会。
进一步巩固和复习数据结构的基础知识。
培养学生结构化程序、模块化程序设计的方法和能力。
提高学生调试程序的技巧和软件设计的能力。
提高学生分析问题、解决问题以及综合利用C语言进行程序设
计的能力。
了解软件的编制过程。
实现的任务:
完成对若干学生的综合情况信息各种管理。
二,设计内容:
1.确定信息的数据结构:
structstudent/*标记为student*/
{
charnum[10];/*学号*/
charname[15];/*姓名*/
intcgrade;/*计算机能力*/
intmgrade;/*社会活动情况*/
integrade;/*英语能力*/
inttotal;/*总分*/
2
floatave;/*平均分*/
intmingci;/*名次*/
};
structnode
{
structstudentdata;/*数据域*/
structnode*next;/*指针域*/
}Node,*Link;/*Node为node类型的结构变量,*Link为node类型的指针变量
*/
2.程序应具有以下基本功能:
添加:
增加一个或几个学生的记录,并可选择继续输入或退出。
查询:
可按学生姓名或学号查找记录,若找到,则显示书的记
录,否则提示未找到,无论查找成功否,应还可选择继续查找
或退出。
删除:
删除已输入的记录。
输入姓名或学号查找要删除的记录,
若找到,提示是否确定删除,若选择是,则删除该信息,若选
择否,则取消;若没找到,提示无此信息。
修改:
修改某学生的记录。
输入姓名并查找,若找到,显示该
学生的所有信息,并可进行修改;否则提示无此信息
3.如有时间,可为程序增加以下功能:
登录模块。
该模块在进入主界面之前先执行,用于对进入系统
的用户进行身份验证,若用户输入正确的用户名及用户密码,
则进入主界面,否则输入超过3次错误则退出程序。
处理方法:
用户名及用户密码可保存在一文件中,校验时从文件中读入数
据进行校验。
在系统中应增加一个用户管理模块,在其中可新
增用户,修改用户信息等。
系统帮助。
显示开发者姓名、班级、开发完成日期、版本号和
指导老师等信息。
三,设计要求:
1.核心数据结构用到的结构体要采用动态内存分配和链表结构。
2.使用文件进行存储和管理。
程序启动时可从文件中读取通信信息,
或从键盘输入通信信息;运行过程中如添加或删除记录时也可对文件进
3
行存取;退出前可选择将通信信息保存到文件中。
3.不同的功能使用不同的函数实现(模块化),对每个函数的功能和
调用接口要注释清楚。
对程序其它部分也进行必要的注释。
4.对系统进行功能模块分析、画出总流程图和各模块流程图。
5.用户界面要求使用方便、简洁明了、美观大方、格式统一。
所有
功能可以反复使用,最好使用菜单。
6.通过命令行相应选项能直接进入某个相应菜单选项的功能模块。
7.所有程序需调试通过。
四、主要功能模块流程图:
(至少画出一个自己所做功能模块的流程图,流程图按教材中规范要求为准。
)
五、系统测试:
(列出对于给定的输入所产生的输出结果。
只写出自己所做功能测试结果)
程序运行实例如下:
1.选择1,运行界面如下:
添加学生信息:
2.选择2,运行界面如下:
修改学生信息:
3.选择3,运行界面如下:
删除学生信息
5.选择5,运行界面如下:
浏览学生信息:
六.设计总结
通过一周的课程设计,我从中受益匪浅,使得我对数据结构这门课有了更深一步的认识。
在设计过程中,我们发现问题,解决问题,一同探讨问题,在老师的帮助下把问题一一解决。
在解决问题的过程中得到了成长,在与同学的合作过程中,我获益良多,提高了自己的团队合作能力和实际动手能力,在亲自动手的同时提升自己,锻炼自己。
通过这次设计,我深深的感受到了做系统是一件十分复杂周密的事情,不能有半点的疏忽,需要一个人有周密的思考能力,分析问题、处理问题的能力,还要有足够的耐心。
七、源程序及系统文件使用说明:
1,程序源
#include
#include
#include
#include
#definePT"%s\t%s\t%d\t%d\t%d\t%d\t%5.1f\n",p->data.num,p->data.name,p->data.cgrade,p->data.mgrade,p->data.egrade,p->data.total,p->data.ave
#definePT_P"%s\t%s\t%d\t%d\t%d\t%d\t%5.1f\t%d\n",p->data.num,p->data.name,p->data.cgrade,p->data.mgrade,p->data.egrade,p->data.total,p->data.ave,p->data.position
#defineST"%s%s%d%d%d",p->data.num,p->data.name,&p->data.cgrade,&p->data.mgrade,&p->data.egrade
#defineTRUE1
#defineFALSE0
#defineULENsizeof(structuser)
#defineLENsizeof(structNode)
//学生数据定义模块
typedefstructstudent{
charnum[10];//学号
charname[15];//姓名
intcgrade;//计算机能力
intmgrade;//社会活动情况
integrade;//英语能力
inttotal;//总分
floatave;//平均分
intposition;//名次
};
typedefstructNode{
inttab;
structstudentdata;
structNode*next;
}Node,*Link;
//用户数据模块定义
typedefstructuser
{
charname[15];
charkey[15];
structuser*next;
}Users,*LUsers;
//全局变量
intcount=0;//统计学生人数
intuser_count=0;//统计用户人数
charsign_in_name[15];//保存用户登陆姓名
structuser*sign_in_head;//保存用户登陆所在的表头,供保存所用
//函数声明
intscan_num(Link,char);
structNode*sort_position(Link);
voidsave_users(LUsers);
structuser*user_load(LUsers);
structuser*sign_up(LUsers);
////此处开始为学生信息模块
//创建学生信息
structNode*creat(void)
{
intcreat_error_info;//创建数据错误信息统计
structNode*p,*q,*scan,*head;
charchoice,compare_name[15];//compare_name用在创建学生信息时避免出现学生号重复的情况
scan=q=head=(Link)malloc(LEN);
head->next=NULL;
printf("Num\tName\tNGrade\tMGrade\tEGrade\n");
choice='y';
while(choice=='y'||choice=='Y')
{
p=(Link)malloc(LEN);
p->next=NULL;
p->tab=0;//初始化每个节点的标记域为0
scanf(ST);
p->data.total=p->data.cgrade+p->data.egrade+p->data.mgrade;
p->data.ave=p->data.total/3.0;
creat_error_info=scan_num(head,p->data.num);//调用scan_num函数排除学号重复的情况
if(creat_error_info!
=1)
{
q->next=p;
q=p;
count++;
printf("\n是否继续创建?
(Y/N):
");
choice=getche();
}
else
{
printf("\n出现学号重复!
是否重新创建?
(Y/N):
");
choice=getche();
}
printf("\n");
}
head=sort_position(head);//调用sort_position函数对名次进行排序
returnhead;
}
//读取学生信息
structNode*load(void)
{
FILE*fp;
Linkp1,p2,head;
charStr[70];//这里申请Str字符数组的作用是为下面的gets以及sscanf所使用,
//申请长度为70是根据所定的结构体数组而定,再次基础是略有增加一点空间
head=NULL;//初始化头指针为空(十分重要)!
if((fp=fopen("c:
\\学生综合信息.txt","r+"))==NULL)//文件使用方式是读写(r+),含义为:
为读写打开一个文本文件
{
printf("打开文件失败!
");
returnhead;//如果打开失败,返回一个NULL头指针
}
if(fgets(Str,sizeof(Str),fp)==NULL)
/*fgets函数原型:
char*fgets(char*buf,intn,FILE*fp)
功能:
从fp指向的文件读取一个长度为(n-1)的字符串,存在起始地址为buf的空间,此处明显存入Str中
返回地址buf,若遇文件结束或出错,返回NULL。
为判断提供条件*/
{
printf("此文件中没有数据!
");
fclose(fp);
returnhead;
}
//有数据,此时创建链表
head=p2=(Link)malloc(LEN);//此处p2作用是作为动态寻址,为新结点的插入作准备
p1=(Link)malloc(LEN);//此处p1作用是动态读取信息
if(head==NULL)
{
printf("分配内存失败!
");
fclose(fp);
exit(0);
}
head->next=NULL;//此处两条语句的作用是确保结点的指针域为空
p1->next=NULL;
do
{
sscanf(Str,"%s%s%d%d%d%d%f%d",p1->data.num,p1->data.name,&p1->data.cgrade,&p1->data.mgrade,&p1->data.egrade,&p1->data.total,&p1->data.ave,&p1->data.position);
//定义函数intsscanf(constchar*str,constchar*format,........);
//函数说明:
sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。
格式转换形式请参考scanf()。
转换后的结果存于对应的参数内。
p2->next=p1;
p2=p1;
count++;
p1=(Link)malloc(LEN);
p1->next=NULL;
}
while(fgets(Str,sizeof(Str),fp)!
=NULL);
fclose(fp);
returnhead;
}
//扫描学号,排除学号重复
intscan_num(Linkh,charnum[])
{
Linkp=h;
if(p->next==NULL)
returnFALSE;
else
{
p=p->next;
while
(1)
{
if(p==NULL)
returnFALSE;
if((strcmp(p->data.num,num))==0)
returnTRUE;
else
p=p->next;
}
}
}
//----------插入学生信息-------------
voidinsert(Linkhead)
{
Linkp;
intinsert_error_info;
charchoice='y';
while(choice=='Y'||choice=='y')
{
p=(Link)malloc(LEN);
printf("\nNum\tName\tNGrade\tMGrade\tEGrade\n");
scanf(ST);
p->data.total=p->data.cgrade+p->data.egrade+p->data.mgrade;
p->data.ave=p->data.total/3.0;
while(strlen(p->data.num)!
=strlen(head->next->data.num))//对前后结点间的学生号进行比较,防止出现学生号录入不统一的情况
{
printf("输入的学生号信息不统一,请重新输入该学生的学号!
\n");
scanf("%s",p->data.num);
}
insert_error_info=scan_num(head,p->data.num);//排除学号不统一的情况
if(head->next!
=NULL&&insert_error_info==0)//此if实现新数据插入链表中,采用的是头插法
{
p->next=head->next;
head->next=p;
count++;//统计学生人数
printf("插入成功!
\n是否继续创建?
是(Y/y)OR否(N/n)");
choice=getche();
}
else
{
printf("新插入的学生号出现重复!
\n错误,是否要重新创建?
是(Y/y)OR否(N/n)");
choice=getche();
}
}
head=sort_position(head);
printf("\n请按任意键继续!
\n");
getche();
}
//修改学生信息
voidmodify(Linkh)
{
charnumber[10];//number数组作为存放学生号所用
Linkp;
charchoice;
printf("请输入需要修改学生的学生号:
");
scanf("%s",number);
for(p=h;strcmp(p->data.num,number)!
=0;p=p->next)//全链表查找
{
if(p->next==NULL)
{
printf("您输入的学生号没有找到!
请重新输入:
\n");
p=h;//重新将表头赋值给p,实现全表循环查找,确保如果有,一定能够找到相关学生号
scanf("%s",number);
}
}
printf("\n您将修改学生号为%s,姓名为%s学生的信息\n\n",p->data.num,p->data.name);
while
(1)
{
intn;//选择变量
printf("请输入需要修改信息的代码并按回车键结束!
\n\n");
printf("1.Num2.Name3.CGrade4.MGrade5.EGrade\n");
scanf("%d",&n);
switch(n)
{
case1:
printf("请输入你要修改后学生号的信息:
");
scanf("%s",p->data.num);break;
case2:
printf("请输入你要修改后姓名的信息:
");
scanf("%s",p->data.name);break;
case3:
printf("请输入你要修改后计算机能力的成绩:
");
scanf("%d",&p->data.cgrade);break;
case4:
printf("请输入你要修改后社会活动情况的成绩:
");
scanf("%d",&p->data.mgrade);break;
case5:
printf("请输入你要修改后英语能力的成绩:
");
scanf("%d",&p->data.egrade);break;
default:
printf("输入有误!
");
}
p->data.total=p->data.cgrade+p->data.egrade+p->data.mgrade;
p->data.ave=p->data.total/3.0;
printf("修改过后的信息如下:
\n");
printf("Num\tName\tCGrade\tMGrade\tEGrade\tTotal\tAve\n");
printf(PT);
printf("\n确认?
是Y否N:
");
choice=getche();
if(choice=='y'||choice=='Y')break;
}
h=sort_position(h);
printf("\n修改成功,按任意键继续!
");
getche();
}
//删除学生信息
voiddel(Linkh)
{
charnumber[10];//存放需要删除教师号
Linkp,q;//p查询指针;q指向p前一节点
charchoice;//循环控制变量
if(h==NULL)
{
printf("删除位置不合法!
");
exit
(1);
}
printf("请输入要删除学生的学号:
");
scanf("%s",number);
for(p=h->next;strcmp(p->data.num,number)!
=0;q=p,p=p->next)//调用strcmp函数实现比较查询
{
if(p->next==NULL)
{
printf("您输入的学生号没有找到!
请重新输入:
\n");
p=h;
scanf("%s",number);
}
}
printf("\n你要删除的学生信息如下,请确认是否删除:
\n\n");
printf("Num\tName\tCGrade\tMGrade\tEGrade\tTotal\tAve\n");
printf(PT);
printf("\n删除?
是Y,否N:
");
choice=getche();
if(choice=='Y'||choice=='y')
{
q->next=p->next;//与删除的结点之间断开
free(p);//释放空间,达到删除数据
printf("\n该学生信息删除成功!
");
count--;//减少教师人数
}
h=sort_position(h);
printf("\n按任意键结束!
");
getche();
}
//查询学生信息
voidfind(Linkh)
{
intn,count=1;//n选择变量,count寻找计数并且作为循环中断标志
charnumber[10],name[10];
Linkp;
printf("请输入按何种方式查询学生信息\n1.按学号2.按姓名\n");
scanf("%d",&n);
switch(n)
{
case1:
{
printf("请输入你要查找的学生学号:
");
scanf("%s",number);
for(p=h;strcmp(p->data.num,number)!
=0;p=p->next)
{
if(p->next==NULL)
{
printf("您输入的学生号没有找到!
请重新输入:
\n");
p=h;
scanf("%s",number);
}
}
printf("你查找的学生信息如下:
\n");
printf("Num\tName\tCGrade\tMGrade\tEGrade\tTotal\tAve\n");
printf(PT);
break;