资源描述
通达学院
程序设计
(2017/2018学年 第1学期)
题 目:学生选修课程系统设计与实现
专 业 计算机科学于技术(嵌入式)
学 生 姓 名
班 级 学 号
指 导 教 师 徐小龙
指 导 单 位 计算机学院·计算机科学与技术系
日 期 2017年10月27日
南京邮电大学通达学院
程序设计
指导教师成绩评定表
题 目
学生姓名
班级学号
专业
评分内容
评分标准
优秀
良好
中等
差
平时成绩
认真对待课程设计,遵守实验室规定,上机不迟到早退,不做和设计无关的事。
设计成果
设计的科学、合理性
功能丰富、符合设题目要求
界面友好、外观漂亮、大方
设计的原创性
设计报告
设计报告正确合理、反映系统设计流程
文档内容详实程度
文档格式规范、排版美观
答辩
简练、准确阐述设计内容,能准确有条理回答各种问题,系统演示顺利。
评分等级
指导教师签名
日期
2017—10-27
备注
评分等级有五种:优秀、良好、中等、及格、不及格
一、 课题内容和要求
学生选修课程系统设计与实现
假定有n门课程,每门课程有课程编号,课程名称,课程性质,总学时,授课学时,实验或上机学时,学分,开课学期等信息,学生可按要求(如总学分不得少于60)自由选课.试设计一选修课程系统,使之能提供以下功能:
(1) 系统以菜单方式工作
(2) 课程信息录入功能(课程信息用文件保存)--输入
(3) 课程信息浏览功能--输出
(4) 查询功能:按学分查询、按课程性质查询
(5) 学生可以选修课程
二、 需求分析
开 始
本系统的功能模块如图所示
主 函 数
进
入
选
课
操
作
统
计
选
课
情
况
浏
览
课
程
信
息
录
入
课
程
信 息
查
询
课
程
信
息
从选课文件中统计信 息
输入学号姓名进行选 开课课
浏览文件中的课程信 息
将课程信息输入文件 中
按 照课 程性 质查 询
课 程
按照学分查询课程信 息
1. 使系统以菜单方式工作:输出个菜单,用于显示以从文件中加载的课程信息和若干个可选的功能选项。根据客户输入的选项来运行不同的功能,运行不同的函数。
2. 录入课程信息:使用户可以将课程信息输入文件
3. 浏览课程信息:使用户可以按照学分或者课程性质浏览文件中的课程信息
4. 进入选课操作:输入学号,姓名进行选课
5. 统计选课情况:从选课文件中统计信息
三、 概要设计
(1)主函数的设计
在主函数中按照提示输入相对应数字进入相应的操作,同时,在输入序号数字错误时,会自动提示“输入错误,请重新输入”,然后,重新输入一个数字,继续进行相应的操作。
(注:输入的数字要在0~5之内)
算法设计如下:
S1: 从键盘上输入一个0~5的数字,进入相应的操作
S2: 如果选择序号1,则进入课程信息录入操作
S3: 如果选择序号2,则进入浏览课程信息操作
S4: 如果选择序号3,则进入查询课程信息操作
S5: 如果选择序号4,则进入学生选择课程操作
S6: 如果选择序号5,则进入统计选课情况操作
S7: 如果选择序号0,则退出学生选课管理系统
S8: 如果选择除0~5的其他操作,则提示“输入错误,请重新输入”
然后返回S1
具体流程图如下:
开 始
主 函 数
输入0~5相 应的操作对应的数字
进行相应的操作
是 否
继 续
是
否
结 束
(2) 录入函数的设计
对于录入函数,就是在D盘建立一个“course.txt"文件,然后通过scanf从键盘上输入课程信息,再通过fprintf将输入的信息保存在文件中,关闭文件.
算法设计如下:
S1: 在D盘建立“course。txt”文件
S2: 提示让学生输入选课门数
S3: 从键盘上输入课程信息并保存
S4: 当指针指向文件尾部,返回S3
具体流程图如下:
开 始
创建文件
输入课程门数
结 束
输入课程信息
保存课程信息
是否指向尾 部
是
结 束
(3) 浏览函数的设计
对于浏览函数,通过fscanf读取文件中的课程信息,然后再通过printf将信息输出
算法设计如下:
S1: 打开“course。txt”文件
S2: 读取文件中的信息
S3: 输出信息
S4: 当指针未指向文件尾部,返回S2
具体流程图如下:
开 始
打开文件
输出课程信息
读取课程信息
否
是否指向尾 部
是
结 束
(4) 查询函数的设计
对于查询函数,输入1或2选择查询方式,如果不是,则重新输入。对于不同方式的查询,如果输入的方式与文件中有相符的,则输出查询结果
算法设计如下:
S1: 选择查询方式
S2: 如果方式是学分查询,输入想查询的学分,打开文件,未指向文件尾部,如果文件中存在,则输出查询结果
S3: 如果方式是课程性质查询,输入想查询的课程性质,打开文件,未指向文件尾部,读取文件信息,如果文件中存在,则输出查询结果
S4: 如果方式数字不存在,则退出查询
具体流程图如下:
开 始
选择查询方式
数字不正确
按
课程性质
按学分查询
打开文件读取
打开文件读取
只 显示 课程 编号、课程 名称 信息,不显 示结 果
是否存在信息
是否存在信息
是
是
否
否
是否指向尾 部
是否指向尾 部
是
是
是
是
退出课程查询
系统
输出课程信息
输出课程信息
结 束
结 束
(5) 选课函数的设计
对于选课函数,先从键盘上输入学号,姓名,课程编号,课程名称,打开“course.txt”文件,如果,课程存在,则进入下一步,建立“student.txt”文件,将选课信息保存在文件中,退出。
算法设计如下:
S1: 输入选课信息,包括学号,姓名,课程编号,课程名称
S2: 打开文件“course.txt”
S3: 如果课程存在,则进行下一步
S4: 建立“student.txt”文件
S5: 保存选课信息
具体流程图如下开 始
:
输入选课信息
打开课程文件
是否存在课程
建立选课文件
读取选课信息保存
读取选课信息保存
否
是否指向尾 部
结 束
(6) 统计函数的设计
对于统计函数,打开“student.txt”文件,读取文件中的选课信息,输出文件中的选课信息,计数,关闭文件
算法设计如下:
S1: 打开“student。txt”文件
S2: 当未指向文件尾部,读取文件中的选课信息
S3: 输出选课信息同时计数
S4: 输出人数
S5: 结束
具体流程图如下:
开 始
打开选课文件
读取选课信息
输出选课信息计数
否
是否指向尾 部
结 束
四、详细设计
1.主函数:构造void main(),实现调用各个功能模块:
学生选课系统执行主流程如图所示,先执行主函数中显示菜单函数,通过循环和按键操作来执行相应的操作。按键的有效键值为0~5之间的任意数值,其他按键为无效输入,会提示“输入错误,请重新输入”,同时,再次用scanf创造再次输入的机会。各个按键的执行功能为:
“1”:录入选修课课程信,调用函数luru();
“2":浏览录入的课程信息,调用函数liulan();
“3":查询课程信息,调用函数chaxun();
“4”:进入选课操作,调用函数chaxun();
“5”:统计选课信息,调用函数tongji();
“0”:退出系统;
int main()
{
int n;
int menu();
int f1();
int luru();
int liulan();
int chaxun();
int xuanke();
int tongji();
printf(”\n ********************** ***********************”);
printf("\n\n ********** 欢迎进入学生选课系统! **********");
menu();
printf(”\n”);
printf(" ******************* the end *********************\n");
printf("\n ********************** ***********************");
printf("\n\n 请 先 选 择 1 进 行 课 程 信 息 录 入:");
scanf(”%d”,&n);
for(;n〉5||n〈0;)
{
printf(”\n 输 入 错 误 !请 重 新 输 入 !\n ”);
scanf("%d”,&n);
}
while(n>0&&n〈6)
{
switch(n)
{
case 1:luru();break;
case 2:liulan();break;
case 3:chaxun();break;
case 4:xuanke();break;
case 5:tongji();break;
}
scanf(”%d",&n);
for(;n〉5||n〈0;)
{
printf(”\n\n");
printf("\n 输 入 错 误 ! 请 重 新 输 入 !\n ”);
scanf(”%d”,&n);
}
system("cls”);
}
if(n==0)
{
printf(" \n\n\n\n\n\n\n”);
printf(" ********** 谢谢使用! **********\n ");
printf(”\n\n\n\n\n");
}
exit(0);
return 0;
}
2. 定义menu函数,f1函数方便调用函数
函数功能及实现:此函数为输出菜单,进入系统后提示可根据供选择的项目进行后续操作。
int menu()
{
int n;
printf("\n\n\n\n");
printf(” 1. 录 入 课 程 信 息\n\n”);
printf(" 2。 浏 览 课 程 信 息\n\n");
printf(” 3. 查 询 课 程 信 息\n\n”);
printf(" 4。 进 入 选 课 操 作\n\n");
printf(" 5. 统 计 选 课 情 况\n\n");
printf(" 0. 退 出 选 课 系 统\n\n”);
return 0;
}
3. 定义课程、选课结构体变量
struct course
{
int num;
char name[20];
char kind[20];
int ttime,mark,term;
}c;
struct student
{
int snum;
int cnum;
char cnam[20];
char snam[20];
}s[500];
4. 定义录入函数,课程信息
函数功能及实现:此函数录入课程信息,在查询、浏览、进入选课,查看选课信息等函数之前。定义指向文件的指针变量*fp,课程信息结构体c通过fopen函数建立文件"course.txt",后输入录入课程的门数,打印表头,通过for循环,用scanf函数从屏幕读取课程信息,并通过fprintf函数将课程信息录入到文件“course。txt”中,最后输出主菜单,返回主程序。
int luru()
{
FILE *fp;
struct course c;
int count;
int i;
if((fp=fopen(”D://course。txt",”w”))==NULL)
{
printf(”cannot open file\n");
exit(0);
}
printf("\n 请 输 入 选 择 的 课 程 门 数:");
scanf(”%d”,&count);
printf("\n\n\n");
f1();
for(i=0;i<count;i++)
{
scanf(”%d%s%s%d%d%d",&c.num,c.name,c。kind,&c.ttime,&c。mark,&c。term);
fprintf(fp,”%d\t%s\t%s\t%d\t%d\t%d\t",c。num,c。name,c。kind,c。ttime,c.mark,c。term);
}
fclose(fp);
printf(”\n 录 入 成 功!\n\n”);
menu();
return 0;
}
5. 定义浏览函数,浏览录入的课程信息
函数功能及实现:此函数先定义指向文件的指针*fp,课程结构体变量c,通过if语句判断文件是否存在,在调用函数f1(),输出表头信息,通过for循环并使用fscanf函数将文件中的课程信息读出并通过printf打印到屏幕上,再通过fclose函数关闭文件。
int liulan()//浏览函数
{
int i=0;
FILE *fp;
struct course c;
if((fp=fopen(”D://course。txt","r"))==NULL)
{
printf(”\ncannot open course!\n”);
exit(0);
}
f1();
while(!feof(fp)&&i<count)
{ fscanf(fp,”%d%s%s%d%d%d”,&c.num,c。name,c.kind,&c.ttime,&c。mark,&c。term);
printf(”%7d%11s%10s%9d%9d%8d\n”,c.num,c。name,c.kind,c.ttime,c。mark,c.term);
i++;
}
fclose(fp);
menu();
return 0;
}
6. 定义查询函数,按照学分和课程性质查询
函数功能及实现:先定义学生结构体变量s,打印相关可供选择的选项,通过scanf函数读取输入字符,打印表头,再使用if语句进行相关选择。如果数“1”,则是按学分查询课程,符合第一个if语句,输入想要查询的学分,程序通过for循环从文件中读取课程信息,并通过printf函数输出满足要求的课程信息;如选择“2",符合第二个if语句,则按照课程性质查询,输入课程性质,程序通过for循环从文件中读取课程信息,并通过printf函数输出满足要求的课程信息;如输入“3”,符合第二个if语句,则按照课程名称查询,输入要课程名称,程序通过for循环从文件中读取课程信息,并通过printf函数输出满足要求的课程信息;查询完成后通过fclose 函数关闭文件,打印主菜单,返回主函数。
int chaxun()
{
FILE *fp;
struct course c;
int score;
int b,i=0;
char kind[20];
printf("\n 1.按 学 分 查 询\n”);
printf("\n 2.按 课 程 性 质 查 询”);
printf(" 请 选 择 查 询 方 式 \n\n 输 入 选 项 数 字:");
scanf(”%d",&b);
for(;b<1||b>2;)
{
printf("\n 输 入 错 误 !请 重 新 输 入 !\n ");
scanf(”%d",&b);
}
if(b==1)
{
printf("\n 输 入 你 要 查 询 的 学 分: ");
scanf(”%d",&score);
if((fp=fopen(”D://course。txt",”r"))==NULL)
{
printf(”\ncannot open course!\n”);
exit(0);
}
f1();
while(!feof(fp)&&i〈count)
{
fscanf(fp,”%d%s%s%d%d%d",&c.num,c。name,c。kind,&c.ttime,&c。mark,&c.term);
if(c.mark==score)
printf(”%7d%11s%10s%9d%9d%8d\n”,c.num,c.name,c。kind,c.ttime,c.mark,c.term);
i++;
}
}
else if(b==2)
{
printf("\n\n 输 入 你 要 查 询 的 课 程 性 质:");
scanf("%s",kind);
if((fp=fopen("D://course.txt","r”))==NULL)//打开文件"course.txt”
{
printf("\ncannot open course!\n”);
}
f1();
while(!feof(fp)&&i<count)
{
fscanf(fp,"%d%s%s%d%d%d”,&c。num,c。name,c。kind,&c.ttime,&c.mark,&c。term);
if(strcmp(c.kind,kind)==0)
printf("%7d%11s%10s%9d%9d%8d\n",c.num,c。name,c.kind,c。ttime,c。mark,c。term);
i++;
}
}
else
{
printf("输入错误!”);
exit(1);
}
fclose(fp);
menu();
return 0;
}
7. 定义选课函数,进入选课操作
函数功能及实现:进入此函数可进行自由选课,首先定义了学生结构体变量s,和课程结构体变量c。选课学生输入自己的学号和要选的课程,通过for循环打开文件并找到所要选择的课程,通过break跳出循环,关闭课程文件“course。txt”并将学生选课信息存入文件“student。txt”中。打印菜单信息,返回主函数.
int xuanke()
{
int t=0,flag;
int i;
/*struct course c;
FILE *fp;
do
{
printf(”\n 请 输 入 学 号 姓 名 课 程 编 号 及 课 程 名 称 :");
scanf("%d%s%d%s”,&s[t]。snum,s[t]。snam,&s[t].cnum,s[t].cnam);
if((fp=fopen(”D://course。txt",”r"))==NULL)//打开文件"course。txt"
{
printf(”\ncannot open course!\n”);
exit(0);
}
while(!feof(fp))
{
fscanf(fp,"%d%s%s%d%d%d”,&c。num,c。name,c。kind,&c.ttime,&c。mark,&c.term);
if((s[t].cnum==c.num)&&(s[t]。cnam==c。name))
t++;
break;
} fclose(fp);
printf("\n 是 否 继 续 ,是 1,否 0 \n ”);
scanf(”%d”,&flag);
if((fp=fopen("D://student.txt",”a+”))==NULL)
{
printf("\ncannot open student!\n”);
exit(0);
}
for(i=0;i<t;i++);
fprintf(fp,"%d\t%s\t%d\t%s\t\n”,s[t].snum,s[t]。snam,s[t]。cnum,s[t].cnam);
fclose(fp);
}while(flag);
printf("\n ********* 恭喜选课成功!*********\n");
menu();
return 0;
}
8.定义统计函数,统计学生选课信息
函数功能及实现:此函数为查看选修课被选择的情况。定义了变量total为了统计选课人数,通过if语句判断是否存在文件“student。txt",通过for循环打印出所有已选课学生的学号、选课课程编号和所选课程的名称,通过计数变量total输出已选课的人数信息。然后打印菜单,返回主函数。
int tongji()//统计函数
{
int total=0;
int t,i=0;
FILE *fp;
if((fp=fopen("D://student。txt",”r"))==NULL)
{
printf("\ncannot open student!\n”);
exit(0);
}
printf("\n 学号 姓名 课程编号及课程名称\n”);
while(!feof(fp))
{
fscanf(fp,”%d%s%d%s\n",&s[i]。snum,s[i].snam,&s[i].cnum,s[i].cnam);
total++;
i++;
}
t=i;
for(i=0;i〈t;i++)
printf("%5d%6s%7d%10s\n",s[i]。snum,s[i].snam,s[i]。cnum,s[i]。cnam);
printf(”\n 选课学生总人数为:%d人”,total);
fclose(fp);
menu();
return 0;
}
源程序代码:
#include<stdio.h〉
#include<string.h〉
#include<stdlib。h〉
struct course
{
int num;
char name[20];
char kind[20];
int ttime,mark,term;
}c;
struct student
{
int snum;
int cnum;
char cnam[20];
char snam[20];
}s[500];
int count;//全局变量
int main()//主函数
{
int n;
int menu();
int f1();
int luru();
int liulan();
int chaxun();
int xuanke();
int tongji();
printf(”\n ********************** ***********************");
printf(”\n\n ********** 欢迎进入学生选课系统! **********");
menu();
printf(”\n");
printf(” ******************* the end *********************\n");
printf(”\n ********************** ***********************");
printf(”\n\n 请 先 选 择 1 进 行 课 程 信 息 录 入:");
scanf(”%d",&n);//防止错误,请重新输入
for(;n>5||n<0;)
{
printf(”\n 输 入 错 误 !请 重 新 输 入 !\n ");
scanf(”%d”,&n);
}
while(n>0&&n<6)
{
switch(n)
{
case 1:luru();break;//录入课程信息
case 2:liulan();break;//浏览课程信息
case 3:chaxun();break;//查询课程信息
case 4:xuanke();break;//进入选课操作
case 5:tongji();break;//统计选课情况
}
scanf("%d",&n);//选择所需操作
for(;n>5||n〈0;)
{
printf(”\n\n”);
printf(”\n 输 入 错 误 ! 请 重 新 输 入 !\n ”);
scanf(”%d”,&n);//防止错误,提示重新输入
}
system("cls”);//清屏
}
if(n==0)
{
printf(” \n\n\n\n\n\n\n");
printf(" ********** 谢谢使用! **********\n ”);
printf("\n\n\n\n\n”);
}
exit(0);//退出选课系统
return 0;
}
int menu()//菜单函数
{
int n;
printf(”\n\n\n\n");
printf(” 1. 录 入 课 程 信 息\n\n");
printf(" 2。 浏 览 课 程 信 息\n\n”);
printf(" 3. 查 询 课 程 信 息\n\n");
printf(” 4. 进 入 选 课 操 作\n\n");
printf(" 5。 统 计 选 课 情 况\n\n");
printf(” 0. 退 出 选 课 系 统\n\n");
return 0;
}
int f1()
{
printf("\n 课程编号 课程名称 课程性质 总学时 学分 开课学期:\n");
return 0;
}
int luru()//录入函数
{
FILE *fp;//定义指向文件的指针
struct course c;
int i;
if((fp=fopen("D://course。txt",”w"))==NULL)//建立文件"course。txt"
{
printf("cannot open file\n”);
exit(0);
}
printf("\n 请 输 入 选 择 的 课 程 门 数:");
scanf(”%d”,&count);
printf("\n\n”);
f1();
for(i=0;i<count;i++)
{
scanf(”%d%s%s%d%d%d",&c。num,c.name,c.kind,&c。ttime,&c.mark,&c。term);
fprintf(fp,”%d\t%s\t%s\t%d\t%d\t%d\t",c.num,c.name,c。kind,c.ttime,c.mark,c.term);
}
fclose(fp);//关闭文件
printf("\n ********* 录入成功!*********\n”);
menu();
return 0;
}
int liulan()//浏览函数
{
int i=0;
FILE *fp;//定义指向文件的指针
struct course c;//定义课程结构体变量
if((fp=fopen(”D://course。txt”,”r”))==NULL)//打开文件”course。txt"
{
printf("\ncannot open course!\n”);
exit(0);
}
f1();
while(!feof(fp)&&i〈count)
{ fscanf(fp,”%d%s%s%d%d%d”,&c。num,c。name,c。kind,&c。ttime,&c。mark,&c.term);
printf(”%7d%11s%10s%9d%9d%8d\n",c。num,c.name,c。kind,c.ttime,c.mark,c.term);
i++;
}
fclose(fp);//关闭文件
menu();
return 0;
}
int chaxun()//查询函数
{
FILE *fp;//定义指向文件的指针
struct course c;//定义课程结构体变量
int score;
int b,i=0;
char kind[20];
printf(”\n 1.按 学 分 查 询\n”);
printf("\n 2.按 课 程 性 质 查 询”);
printf(" 请 选 择 查 询 方 式 \n\n 输 入 选 项 数 字:”);
scanf("%d”,&b);//防止错误,提示重新输入
for(;b<1||b〉2;)
{
printf(”\n 输 入 错 误 !请 重 新 输 入 !\n ");
scanf("%d",&b);
}//按学分查询
if(b==1)
{
printf(”\n 输 入 你 要 查 询 的 学 分: ");
scanf(”%d”,&score);
if((fp=fopen(”D://course.txt",”r"))==NULL)
{
printf(”\ncannot open course!\n");
exit(0);
}
f1();
while(!feof(fp)&&i<count)//当没有指向文件尾部,读取文件“course。txt”中的数据
{
fscanf(fp,”%d%s%s%d%d%d”,&c。num,c。name,c。kind,&c.ttime,&c。mark,&c.term);
if(c.mark==score)//比较输入的分数和结构体中的分数,如果相同,输出那组数据
printf("%7d%11s%10s%9d%9d%8d\n”,c。num,c.name,c。kind,c.ttime,c.mark,c.term);
i++;
}
}
else if(b==2)//按课程性质查询
{
printf("\n\n 输 入 你 要 查 询 的 课 程 性 质:”);
scanf("%s”,kind);
if((fp=fopen(”D://course。txt”,"r"))==NULL)//打开文件”course。txt"
{
printf(”\ncannot open course!\n");
}
f1();
while(!feof(fp)&&i<count)//当没有到达文件尾部,读取“course.txt”中的数据
{
fscanf(fp,"%d%s%s%d%d%d",&c.num,c。name,c.kind,&c.ttime,&c.mark,&c.term);
if(strcmp(c.kind,kind)==0)//比较输入的字符串与原文件中的课程性质,如果相同,
输出那组数据
printf(”%7d%11s%10s%9d%9d%8d\n”,c.num,c。name,c。kind,c。ttime,c.mark,c.term);
i++;
}
}
else
{
printf(”输入错误!");//选择错误,就退出
exit(1);
}
fclose(fp);
men
展开阅读全文