西安郵電大學
C语言课程设计报告
题 目: 学生成绩管理系统
院系名称: 计算机学院
专业名称: 计算机科学与技术
班 级: 计科1102
学生姓名: 冯佳新
学号(8位): 04111067
指导教师: 李川
设计起止时间:20##年6月6日~20##年6月15日
一. 设计目的
1. 强化上机动手能力,在理论和实践的基础上进一步巩固《C语言程序设计》课程学习的内容,掌握工程化软件设计的基本方法
2. 学会将知识应用于实际的方法,提高分析和解决问题的能力,增加综合能力
3. 为后续各门计算机课程的学习打下坚实基础
二. 设计内容
1、密码登录;
2、通过键盘输入学生信息,包括学生学号、姓名、成绩;
3、将输入的信息保存到指定文件中;
4、从文件中读取学生信息;
5、显示全部学生信息;
6、按学生总分进行降序排序;
7、删除学生信息;
8、查找学生信息,可以通过学号查找,也可以通过姓名查找;
9、统计学生信息,统计出最高分和学生人数;
10、退出系统;
三.概要设计
1.功能模块图;
2.各个模块详细的功能描述。
1、密码登录:进入系统前需输入密码口令,此处的密码分为管理员登录密码“abcde”,学生登录密码“12345”;
2、输入信息:输入学生信息,包括:学号、姓名、成绩;
3、显示信息:显示输入的信息或者经过处理后的信息
4、查找信息:查找学生信息,可以按学号查找,也可以按姓名查找;
5、修改信息:修改学生的任何信息;
6、删除信息:通过查找学生姓名删除该学生信息;
7、排序信息:将输入的学生信息排序,按总分成绩降序排列;
8、统计信息:统计出所有信息中的最高分成绩的学生的信息和学生人数。
四.详细设计
1.功能函数的调用关系图
2.各功能函数的数据流程图
1、主函数模块
2、输入模块
2、输出与排序模块
3、删除与修改信息模块
4、统计信息模块
4、查找信息模块
3.重点设计及编码
此程序的重点是既能把学生信息保存到文件中,又能保存到磁盘中,方便实用与读取,代码如下:
struct student *creat(struct student *p)//创建链表
{
struct student *p1 = NULL;
p1 = (struct student*)malloc(sizeof (struct student));
p -> next = p1;
p1 -> next = NULL;
printf("请输入要添加的学生的信息\n");
printf("学号:"); scanf("%s",p1 -> num);
printf("姓名: "); scanf("%s",p1 -> name);
printf("数学成绩:"); scanf("%d",&p1 -> scorem);
printf("英语成绩:"); scanf("%d",&p1 -> scoree);
printf("C成绩:"); scanf("%d",&p1 -> scorec);
p1 -> sum = 0;
p1 -> sum = p1 -> scorem + p1 -> scorec + p1 -> scoree;
printf("总分:%d",p1 -> sum);
return p1;
}
void save1(struct student *p)//将链表从内存保存到文件中
{
FILE *fp;
if ((fp = fopen("d:\\学生成绩管理系统.txt","ab+")) == NULL)
printf("创建失败!\n");
while(p != NULL)
{
fwrite(p,sizeof(struct student),1,fp);
p = p -> next;
}
fclose(fp);
printf("保存成功!\n");
}
void save2(struct student *p)//将以变动的链表信息存入到文件中
{
FILE *fp;
if ((fp = fopen("d:\\学生成绩管理系统.txt","wb")) == NULL)
printf("创建失败!\n");
while(p != NULL)
{
fwrite(p,sizeof(struct student),1,fp);
p = p -> next;
}
fclose(fp);
}
struct student *read()//把文件中的数据读到链表中
{
FILE *fp;
struct student *head=NULL,*p1=NULL,*p2=NULL;
if ((fp=fopen ("d:\\学生成绩管理系统.txt","rb+"))==NULL)
{
printf ("读取时,文件打开失败!\n");
return NULL;
}
head=p1=(struct student *)malloc (sizeof (struct student ));
while (fp != NULL)
{
if (fread(p1,sizeof (struct student ),1,fp) != 1) break;
p1 -> next = (struct student *)malloc (sizeof (struct student ));
p2= p1;
p1= p1 -> next;
}
p2->next = NULL;
fclose (fp);
return head;
}
五.测试数据及运行结果
1. 正常测试数据和运行结果
1.按总分排序
2.删除某个学生信息
3. 查找学生信息
2. 异常测试数据及运行
1. 删除信息出现异常
2.修改学生信息出现异常
六.调试情况,设计技巧及体会
1、对自己设计进行评价
1) 不够细心,开始的时候出现很多错误
2) 没有写登录函数
3) 写的过于简短,且大部分都是书上照抄的
2 .调试上得到的体会:在最后的调试过程中,发现有时候系统报错,指出了错误所在的具体位置,可是检查的时候发现该位置并未出错,这样的错误首先要查找前后几行,如果还未检查出错误,那就很有可能在该函数的首部或是主函数的调用语句中出现错误。发现该部分并未出现语法错误,即编译不报错,程序运行后,有时候会出现意想不到的结果,会在想不到的地方跳出程序,甚至不知道程序的什么地方就跳出了,用在不同的地方加不必要的printf语句!以检查是否运行到printf语句。
3.设计上得到的体会:在初步设计时要明确要使用的数据结构和类型,明确设计的基本思想,清楚所写程序的逻辑结构和执行顺序,在调试时才能在出现问题时及时的找到问题的所在.在完成了初步的设计并调试完成后,要进一步优化程序的结构,使程序更简洁,执行效率更高.
总之,第一次完成比较正式的程序,在开始的时候遇到了不少问题,包括怎么排序,怎么添加,怎么查找,怎么删除等一系列问题,但我并没有慌张,而是由一个问题入手,最后将它们一一攻破,顺利而又艰难的完成了这次任务;通过这次实习,我的编程能力得到了很大的提高,算法思路也比以前清晰多了,基本上掌握了C语言的课程内容,虽然只有为期两周的实习,但是我的C语言还是得到了进一步的提高。不过要想使自己的水平提高,还有待练习。虽然实习结束了,但是以后在工作中可能会经常使用,这次的实习的确是一个很好的锻炼机会,它一定会使我受益终身的!
七.参考文献
《C语言程序设计》 (第二版),
《数据结构(C语言)》 清华大学出版社
八.附录:
源代码(电子版)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student
{
char num[9];
char name[9];
int scorem;
int scoree;
int scorec;
int sum;
struct student *next;
};
struct student *creat(struct student *p)//创建链表
{
struct student *p1 = NULL;
p1 = (struct student*)malloc(sizeof (struct student));
p -> next = p1;
p1 -> next = NULL;
printf("请输入要添加的学生的信息\n");
printf("学号:"); scanf("%s",p1 -> num);
printf("姓名: "); scanf("%s",p1 -> name);
printf("数学成绩:"); scanf("%d",&p1 -> scorem);
printf("英语成绩:"); scanf("%d",&p1 -> scoree);
printf("C成绩:"); scanf("%d",&p1 -> scorec);
p1 -> sum = 0;
p1 -> sum = p1 -> scorem + p1 -> scorec + p1 -> scoree;
printf("总分:%d",p1 -> sum);
return p1;
}
void save1(struct student *p)//将链表从内存保存到文件中
{
FILE *fp;
if ((fp = fopen("d:\\学生成绩管理系统.txt","ab+")) == NULL)
printf("创建失败!\n");
while(p != NULL)
{
fwrite(p,sizeof(struct student),1,fp);
p = p -> next;
}
fclose(fp);
printf("保存成功!\n");
}
void save2(struct student *p)//将以变动的链表信息存入到文件中
{
FILE *fp;
if ((fp = fopen("d:\\学生成绩管理系统.txt","wb")) == NULL)
printf("创建失败!\n");
while(p != NULL)
{
fwrite(p,sizeof(struct student),1,fp);
p = p -> next;
}
fclose(fp);
}
struct student *read()//把文件中的数据读到链表中
{
FILE *fp;
struct student *head=NULL,*p1=NULL,*p2=NULL;
if ((fp=fopen ("d:\\学生成绩管理系统.txt","rb+"))==NULL)
{
printf ("读取时,文件打开失败!\n");
return NULL;
}
head=p1=(struct student *)malloc (sizeof (struct student ));
while (fp != NULL)
{
if (fread(p1,sizeof (struct student ),1,fp) != 1) break;
p1 -> next = (struct student *)malloc (sizeof (struct student ));
p2= p1;
p1= p1 -> next;
}
p2->next = NULL;
fclose (fp);
return head;
}
struct student *input()//添加函数
{
char ch;
struct student *p = NULL,*head=NULL;
head=p = (struct student*)malloc(sizeof(struct student));
p-> next = NULL;
printf("请输入要添加的学生的信息\n");
printf("学号:"); scanf("%s",p -> num);
printf("姓名: "); scanf("%s",p -> name);
printf("数学成绩:"); scanf("%d",&p -> scorem);
printf("英语成绩:"); scanf("%d",&p -> scoree);
printf("C成绩:"); scanf("%d",&p -> scorec);
p -> sum = 0;
p -> sum = p -> scorem + p -> scorec + p -> scoree;
printf("总分:%d",p -> sum);
for (;;)
{
printf ("\n是否继续输入学生信息?( y / n ):\n");
getchar( );
ch = getchar ( );
if (ch == 'y'|| ch == 'Y')
p = creat(p);
else if(ch=='n'|| ch=='N')
{
save1 (head);
break;
}
else
printf ("您的输入有误,请重新输入,");
}
return p->next;
}
struct student *output()//输出函数,查看全部学生信息
{
struct student *p ;
p = read();
if(read==NULL)
exit(1);
printf("\n *************************STUDENT***********************\n");
printf(" -------------------------------------------------------\n");
printf(" | 学号 | 姓名 | 数学 | 英语 | C语言 | 总分 |\n");
printf(" -------------------------------------------------------\n");
while (p != NULL)
{
p -> sum = 0;
p -> sum = p -> scorem + p -> scoree + p -> scorec;
printf(" | %4s | %-4s | %3d | %3d | %3d | %3d |\n",p->num,
p->name,p->scorem,p->scoree,p->scorec,p->sum);
printf(" -------------------------------------------------------\n");
p = p -> next;
}
return p;
}
struct student *search()//查找函数
{
int n;
char a[9],b[9];
struct student *p = NULL,*head = NULL;
printf("请您选择要查找的方式:1 按姓名 2 按学号\n");
scanf("%d",&n);
if(n==1)
{
printf("请输入您要查找的学生的姓名:\n");
scanf("%s",a);
p=head=read();
while(p!=NULL)
{
if(p==NULL)
{
printf("对不起,没有您要找的人。\n");
}
if(strcmp(p -> name,a)==0)
{
printf("\n *************************STUDENT***********************\n");
printf(" -------------------------------------------------------\n");
printf(" | 学号 | 姓名 | 数学 | 英语 | C语言 | 总分 |\n");
printf(" -------------------------------------------------------\n");
printf(" | %4s | %-4s | %3d | %3d | %3d | %3d |\n",p->num,
p->name,p->scorem,p->scoree,p->scorec,p->sum);
printf(" -------------------------------------------------------\n");
break;
}
p=p->next;
}
}
if(n==2)
{
printf("请输入您要查找的学生的学号:\n");
scanf("%s",b);
p=head=read();
while(p!=NULL)
{
if(p==NULL)
{
printf("对不起,没有您要找的人。\n");
}
if(strcmp(p -> num,b)==0)
{
printf("\n *************************STUDENT***********************\n");
printf(" -------------------------------------------------------\n");
printf(" | 学号 | 姓名 | 数学 | 英语 | C语言 | 总分 |\n");
printf(" -------------------------------------------------------\n");
printf(" | %4s | %-4s | %3d | %3d | %3d | %3d |\n",p->num,
p->name,p->scorem,p->scoree,p->scorec,p->sum);
printf(" -------------------------------------------------------\n");
break;
}
p=p->next;
}
}
return head;
}
struct student *dele()//删除函数
{
struct student *p1=NULL,*p2=NULL,*head=NULL;
char a[9];
output();
printf ("请输入需要删除信息的人的姓名:\n");
scanf ("%s",a);
p1=head=read();
if(head==NULL)
{
printf("对不起,暂时没有信息,无法删除。\n");
}
while (head!=NULL)
{
if(strcmp(a,head -> name) != 0 && p1->next!=NULL )
{
p2=head ;
head= head->next ;
if(head==NULL) break;
}
if(strcmp(a,head -> name) == 0 && p1==head)
{
p1=head->next ;
}
if(strcmp(a,head->name)==0)
{
p2->next=head->next;
save2(p1);
printf("该学生的信息删除成功!");
break;
}
}
if(head==NULL)
printf("对不起,没有该学生的信息。\n");
return head;
}
struct student *change()//修改函数
{
int a;
char x[9];
struct student *p = NULL,*head = NULL,*q = NULL;
output();
p = head = read();
printf("请输入要修改的人的姓名:\n");
scanf("%s",x);
if(p == NULL)
{
printf("没有这个人!\n");
exit(1);
}
while (p != NULL)
{
if (strcmp(p -> name,x) == 0)
{
q = p;
break;
}
p = p -> next;
}
if(p!=NULL)
{
printf("请选择修改的内容:\n");
printf("1.姓名\n");
printf("2.学号\n");
printf("3.数学成绩\n");
printf("4.英语成绩\n");
printf("5.C成绩\n");
do
{
scanf ("%d",&a);
if(a < 0 || a > 6)
printf ("您输入的数字有误,请重新输入:\n");
}while (a<=0||a>=6);
switch (a)
{
case 1 : printf("请输入更改后的姓名:\n"); scanf("%s",p -> name); break;
case 2 : printf("请输入更改后的学号:\n"); scanf("%s",p -> num); break;
case 3 : printf("请输入更改后的数学成绩:\n");scanf("%d",&p -> scorem);break;
case 4 : printf("请输入更改后的英语成绩:\n");scanf("%d",&p -> scoree);break;
case 5 : printf("请输入更改后的C成绩:\n"); scanf("%d",&p -> scorec);break;
}
p->sum =0;
p->sum=p->scorem +p->scoree +p->scorec ;
printf("更改后的总分:%d",p->sum);
save2 (head);
output();
}
if(p==NULL)
{
printf("对不起,没有这个人。\n");
}
return head;
}
struct student *sortsum(struct student *head)//排序函数
{
struct student *p,*p1,*p2,*p3;
struct student m, n;
if (head == NULL) return NULL;
m.next=head;
p=&m;
while (p->next!=NULL)
{
p=p->next;
}
p=p->next=&n;
while (p!=m.next)
{
p3=&m;
p1=p3->next;
p2=p1->next;
while (p2!=p)
{
if ((p1 -> sum) < (p2 -> sum) )
{
p1->next=p2->next;
p2->next=p1;
p3->next=p2;
p3=p2;
p2=p1->next;
}
else
{
p3=p1;
p1=p2;
p2=p2->next;
}
}
p=p1;
}
while (p->next!=&n)
{
p=p->next;
}
p->next=NULL;
return m.next;
}
struct student *outputsortsum()//总分排序输出
{
int i=0;
struct student *head = NULL , *p = NULL;
head = read();
p = sortsum(head);
printf("\n *************************STUDENT****************************\n");
printf(" ------------------------------------------------------------\n");
printf(" | 名次 | 学号 | 姓名 | 数学 | 英语 | C语言 | 总分 |\n");
printf(" ------------------------------------------------------------\n");
while(p != NULL)
{
i++;
printf(" | %3d | %4s | %-4s | %3d | %3d | %3d | %3d |\n",i,p->num,
p->name,p->scorem,p->scoree,p->scorec,p->sum);
printf(" ------------------------------------------------------------\n");
p=p->next;
}
return head;
}
struct student *statistic()//统计函数
{
int m = 0;
struct student *head=NULL;
struct student *p,*q;
p = head = read();
while( p != NULL)
{
m++;
p = p -> next;
}
printf("总共有%d个学生信息.\n\n",m);
q= sortsum(head);
printf("分数最高的学生的信息:\n");
printf("\n ***********************STUDENT*************************\n");
printf(" -------------------------------------------------------\n");
printf(" | 学号 | 姓名 | 数学 | 英语 | C语言 | 总分 |\n");
printf(" -------------------------------------------------------\n");
printf(" | %4s | %-4s | %3d | %3d | %3d | %3d |\n",q->num,
q->name, q->scorem,q->scoree,q->scorec,q->sum);
printf(" -------------------------------------------------------\n");
return head;
}
void mima1 ()
{
while(1)
{
int a=1;
int i;
char ch[10];
char num[20]={"abcde"};
printf("进入管理员成绩管理系统之前请先输入密码\n");
printf("请输入您的密码 :\n");
for(i=0;i<10;i++)
{
ch[i]=getch();
if(ch[i]==13 ) break;
putchar('*');
}
ch[i]='\0';
if(strcmp(num,ch)==0)
a = 0;
if(a==0)
{
printf("\n欢迎进入管理员管理系统 !\n");
getchar();
break;
}
else
{
printf("\n这个密码是错误的! ");
printf("\n请输入正确的密码:");
}
}
}
void mima2 ()
{
while(1)
{
int a=1;
int i;
char ch[10];
char num[20]={"12345"};
printf("进入学生成绩管理系统之前请先输入密码\n");
printf("请输入您的密码 :\n");
for(i=0;i<10;i++)
{
ch[i]=getch();
if(ch[i]==13 ) break;
putchar('*');
}
ch[i]='\0';
if(strcmp(num,ch)==0)
a = 0;
if(a==0)
{
printf("\n欢迎进入学生成绩管理系统 !\n");
getchar();
break;
}
else
{
printf("\n这个密码是错误的! ");
printf("\n请输入正确的密码:");
}
}
}
void menu1()
{
system("cls");
printf("\n\n 欢迎进入管理员管理系统!\n\n");
printf("\n *******************************主菜单****************************\n");
printf(" * 1 添加学生成绩 *\n");
printf(" * * 2 查找学生成绩 * *\n");
printf(" * * * 3 删除指定学生 * * *\n");
printf(" * * * 4 修改学生信息 * * *\n");
printf(" * * * 5 总分排序信息 * * *\n");
printf(" * * 6 查看全部信息 * *\n");
printf(" * 7 统计学生人数 *\n");
printf(" * 8 停止程序运行 *\n");
printf(" *****************************************************************\n");
}
void menu2()
{
system("cls");
printf("\n\n 欢迎进入学生管理系统!\n\n");
printf("\n *******************************主菜单****************************\n");
printf(" * * 1 查找学生成绩 * *\n");
printf(" * * * 2 总分排序信息 * * *\n");
printf(" * * * 3 查看全部信息 * * *\n");
printf(" * * * 4 统计学生人数 * * *\n");
printf(" * * 5 停止程序运行 * *\n");
printf(" *****************************************************************\n");
}
main()
{
int a,m;
int b = 1;
printf("\n\t ******************************************************");
printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
printf("\n ★★★★★★★★★★★★★★★★★★★★★★★★★★★\n");
printf("\n\t 西安邮电大学\n\n");
printf("\n\t 教务管理系统欢迎您!\n\n");
printf("\n 请选择您要进入的管理系统 \n\n");
printf(" 1.管理员管理系统。\n\n");
printf(" 2.学生管理系统。\n\n");
printf(" 3.退出系统!\n\n");
printf(" 请您选择: ");
printf("\n\n ★★★★★★★★★★★★★★★★★★★★★★★★★★★");
printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
printf("\n\t ******************************************************\n");
scanf("%d",&m);
if(m==1)
{
system("cls");
mima1();
}
if(m==2)
{
system("cls");
mima2();
}
while (b == 1)
{
if(m==1)
{
menu1();
scanf("%d",&a);
switch(a)
{
case 1 : input(); break;
case 2 : search(); break;
case 3 : dele(); break;
case 4 : change(); break;
case 5 : outputsortsum(); break;
case 6 : output(); break;
case 7 : statistic(); break;
case 8 : exit(1);
default : printf("输入错误!\n");break;
}
printf("\n\n请选择接下来的操作:\n");
printf(" 1 . 返回主菜单 2 . 退出程序\n");
scanf("%d",&b);
}
if(m==2)
{
menu2();
scanf("%d",&a);
switch(a)
{
case 1 : search(); break;
case 2 : outputsortsum(); break;
case 3 : output(); break;
case 4 : statistic(); break;
case 5 : exit(1);
default : printf("输入错误!\n");break;
}
printf("\n\n请选择接下来的操作:\n");
printf(" 1 . 返回主菜单 2 . 退出程序\n");
scanf("%d",&b);
}
if(m==3)
exit (1);
}
}