学生选修课程系统设计

1、需求分析

系统以菜单方式工作,因而要提供键盘式选择菜单以实现功能选择;由于课程信息要用文件保存,因而要提供文件的输入输出操作;由于要浏览信息,所以要提供显示功能;要实现查询功能,故要提供查找操作。

2、总体设计

整个系统可以设计为信息输入模块、信息查询模块以及信息浏览模块。

3、详细设计

数据结构采用结构体,这里采用课程信息结构体和学生选课信息结构体。

Struct

{

Char courseCode[10]; //课程编号

Char courseName[20]; //课程名称

Char courseType[10]; //课程类别

Int totalPeriod; //总学时

Int classPeriod; //授课学时

Int experiPeriod; //上机学时

Float creditHour; //学分

Int term; //开课学期

}CourseInfo[N]; //课程信息结构体

Struct

{

Int stuNo; //学号;

Char courseCode[10]; //课程编号

}StuCourInfo[N]; //学生选课信息结构体

(1) 信息输入模块

从键盘输入课程信息和学生选课信息,写入文件。(fwrite, fprintf)

(2)信息浏览模块

分屏显示课程信息,每屏10条课程记录,按任意键继续。从文件中读数据(fread,fscanf),然后再显示。

(3)信息查询模块

通过菜单选择查询字段,可以按照课程编号、课程名称、课程性质、开课学期、学分对课程信息文件进行查找,查找算法可以选择基本查找、二分查找等算法。

1、首先在项目文件夹内(.c文件同级文件夹)创建class.txt文件和student.txt文件,作为系统的数据文件进行保存。

2、在初次运行系统时,建议先选择课程可学生数据添加选项,因为数据文件中不存在数据。

3、本系统最大选课数在15门以内,超出的不计。

4、源码如下:

#include#include#include//需要用到strcmp函数 //宏定义#define LEN 15//姓名和学号的最大字符数.文件URL路径长度,最多选课数 #define N 50//最大学生人数,课程数int n = 0, c = 0, t = 1;//n代表当前学生人数,c表示课程数,t用来控制整个程序的执行,以及程序的退出; int m = 0,M=0;//m添加的学生人数,M添加的课程数//函数声明void menu();//主菜单函数void readInfo();//数组初始化void select();//操作选择void help();//使用帮助 void increaseClass(); //增加课程信息void increaseStudent(); //增加学生信息void classDisplay(); //课程浏览void studentDisplay();//学生浏览void save(int f);//信息文件保存void find();//查找void findStudent();void findClass();void exitSys();//退出函数 struct Class{char courseCode[10];//课程编号;001char courseName[20];//课程名称;大学英语char courseType[10];//课程类型;必修int totalPeriod;//总学时;60int classPeriod;//授课学时;40int experiPeriod;//上机学时;20float creditHour;//学分;4int term;//开课学期;1为上学期,2为下学期}CourseInfo[N];struct Student{int stuNo;//学号0000;char courseCode[LEN][10];//课程编号;}StuCourInfo[N];void menu(){printf("\n\n");printf("*****************************************************\n");printf("* 学生选修课程系统*\n");printf("*****************************************************\n");printf("********************系统功能菜单*********************\n");printf("-----------------------------------------------------\n");printf("**1、使用帮助\n\n");printf("**2、增加课程信息\n\n");printf("**3、增加学生信息\n\n");printf("**4、课程浏览\n\n");printf("**5、学生浏览\n\n");printf("**6、查询\n\n");printf("**0、退出系统\n\n");printf("-----------------------------------------------------\n");printf("*****************************************************\n\n");}//初始化数组函数void readInfo() {//课程初始化int i=0;int j = 0,flag=0;FILE* fp = fopen("class.txt", "r"); //打开文件;fopen()为C语言内置的文件打开函数。if (NULL == fp){printf("打开文件失败!!\n");exit(0);//退出整个程序}while(!feof(fp))//内置函数,判断文件指针所指文件内有无数据,此处在文件数据为空的时候依然会进入,所以数据默认为1条。{fscanf(fp, "%s %s %s %d %d %d %f %d\n",&CourseInfo[i].courseCode,&CourseInfo[i].courseName,&CourseInfo[i].courseType,&CourseInfo[i].totalPeriod,&CourseInfo[i].classPeriod,&CourseInfo[i].experiPeriod,&CourseInfo[i].creditHour,&CourseInfo[i].term);//文件数据读取函数c++;i++;}fclose(fp); //关闭文件//学生初始化FILE* fp1 = fopen("student.txt", "r"); //打开文件if (NULL == fp1){printf("打开文件失败!!\n");exit(0);}i = 0;while (!feof(fp1)){fscanf(fp1, "%d ",&StuCourInfo[i].stuNo);for (j = 0; j  0){do{//课程号输入及查重flag = 1;while (flag){flag = 0;printf("----------------------------------------------\n");printf("\n请输入第%d个课程编号(例:001):\n", i + 1);scanf("%s", &CourseInfo[i].courseCode);//判断课程号是否重复:for (j = 0; j < i; j++){if (strcmp(CourseInfo[i].courseCode, CourseInfo[j].courseCode) == 0)//字符串比较函数相等为0{printf("\n该课程已存在,请重新输入:\n");flag = 1;break;}}}//其他信息录入printf("请输入第%d个课程名称(例:大学英语):\n", i + 1);scanf("%s",&CourseInfo[i].courseName);printf("请输入第%d个课程类型(例:必修):\n", i + 1);scanf("%s", &CourseInfo[i].courseType);printf("请输入第%d个课程总学时(例:60):\n", i + 1);scanf("%d", &CourseInfo[i].totalPeriod);printf("请输入第%d个课程授课学时(例:40):\n", i + 1);scanf("%d", &CourseInfo[i].classPeriod);//实验学时为总学时-授课学时CourseInfo[i].experiPeriod = CourseInfo[i].totalPeriod - CourseInfo[i].classPeriod;printf("请输入第%d个课程上机学时为:\n%d\n", i + 1,CourseInfo[i].experiPeriod);printf("请输入第%d个课程学分(例:4):\n", i + 1);scanf("%f", &CourseInfo[i].creditHour);printf("请输入第%d个课程开课学期(例:1:前半年;2:后半年):\n", i + 1);scanf("%d", &CourseInfo[i].term);i++;printf("----------------------------------------------\n");} while (i<c+M);//输入的课程数量没有达到;}c += M;//课程数更新。save(1);//课程保存system("pause");system("cls");}//f=0表示为学生文件写入;f=1表示为课程文件写入。void save(int f) {//数据写入:int i,j;FILE* fp;char filename[LEN];//文件名class.txt和student.txtif (f == 0){strcpy(filename, "student.txt");if ((fp = fopen(filename, "a")) == NULL){printf("打开文件失败!\n");exit(0);}for (i = n-m; i < n; i++){//可用sprintf(strStuNo,"%d",StuCourInfo[i].sruNo)//也可用char *_itoa_s(int i,char *s,int radix);//i为要转换为字符的数字;*s为转换后的指向字符串的指针;radix为转换后的字符串指针。/*if (fwrite(&StuCourInfo[i], sizeof(struct Student), n, fp) != 1)printf("保存失败!!\n");*/char strStuNo[10];sprintf(strStuNo,"%d", StuCourInfo[i].stuNo );//内置将基本数据型转换为字符串的函数fputs(strStuNo, fp);fputs(" ", fp);for (j = 0; j < LEN; j++){fputs(StuCourInfo[i].courseCode[j], fp);fputs(" ", fp);}fputs("\n", fp);}m = 0;//添加人数清零}else{strcpy(filename, "class.txt");if ((fp = fopen(filename, "a")) == NULL){printf("打开文件失败!\n");exit(0);}for (i = c-M; i  0){do{//学生号输入及查重flag = 1;while (flag){flag = 0;printf("----------------------------------------------\n");printf("\n请输入第%d个学生学号(例:0001):\n", i + 1);scanf("%d", &StuCourInfo[i].stuNo);//判断学号是否重复:for (j = 0; j < i; j++){if (StuCourInfo[i].stuNo==StuCourInfo[j].stuNo){printf("该学号已存在,请重新输入:\n");flag = 1;break;}}}//其他信息录入printf("**********************************************\n");printf("请输入该学生一共选修课程数:\n");scanf("%d", &x);printf("**********************************************\n");for (j = 0; j < x; j++){printf("\n请输入第%d个学生第%d个选修课程号(例:001:大学英语):\n", i + 1,j+1);scanf("%s", &StuCourInfo[i].courseCode[j]);}for (; j < LEN; j++){strcpy(StuCourInfo[i].courseCode[j], "*");//字符串赋值}i++;printf("----------------------------------------------\n");} while (i < n + m);//输入的学生人数没有达到;}n += m;//人数更新。save(0);//学生保存system("pause");system("cls");}//查询结果不需要清屏void classDisplay(){int i;system("cls");//清屏printf("----------------------------------------------\n");printf("当前所有课程信息展示:\n");for (i = 0; i < c; i++){printf("%d",i+1);printf("-课程编号:%s\t",CourseInfo[i].courseCode);printf("-课程名称:%s\t", CourseInfo[i].courseName);printf("-课程类型:%s\t", CourseInfo[i].courseType);printf("-总学时:%d\t", CourseInfo[i].totalPeriod);printf("-授课学时:%d\t", CourseInfo[i].classPeriod);printf("-上机学时:%d\t", CourseInfo[i].experiPeriod);printf("-学分:%.1f\t", CourseInfo[i].creditHour);printf("-开课学期:%d\t\n",CourseInfo[i].term);if ((i+1) % 10 == 0){system("pause");system("cls");}}printf("展示完成!!\n");printf("----------------------------------------------\n");system("pause");}void studentDisplay(){int i,j;system("cls");//清屏printf("----------------------------------------------\n");printf("当前所有学生信息展示:\n");for (i = 0; i 根据课程编号查询课程\n");printf("2-->根据课程名称查询课程\n");printf("3-->根据课程类别查询课程\n");printf("4-->根据开课学期查询课程\n");printf("5-->根据课程学分查询课程\n");printf("请输入您的查询条件编号:\n");int choice = 0;scanf("%d", &choice);if (choice == 1) {printf("请输入课程编号:\n");char courseCode[10];scanf("%s", courseCode);for (int i = 0; i < c; i++) {if (strcmp(courseCode, CourseInfo[i].courseCode) == 0) {printf("--》课程编号:%s 课程名称:%s 课程类型:%s 总学时:%d 授课学时:%d 上机学时:%d 学分:%.1f 开课学期:%d\n",CourseInfo[i].courseCode,CourseInfo[i].courseName,CourseInfo[i].courseType,CourseInfo[i].totalPeriod,CourseInfo[i].classPeriod,CourseInfo[i].experiPeriod,CourseInfo[i].creditHour,CourseInfo[i].term);}}printf("数据已经全部显示!\n");}else if (choice == 2) {printf("请输入课程名称:\n");char courseName[10];scanf("%s", courseName);for (int i = 0; i < c; i++) {if (strcmp(courseName, CourseInfo[i].courseName) == 0) {printf("%s %s %s %d %d %d %f %d\n",CourseInfo[i].courseCode,CourseInfo[i].courseName,CourseInfo[i].courseType,CourseInfo[i].totalPeriod,CourseInfo[i].classPeriod,CourseInfo[i].experiPeriod,CourseInfo[i].creditHour,CourseInfo[i].term);}}printf("数据已经全部显示!\n");}else if (choice == 3) {printf("请输入课程类别:\n");char courseType[10];scanf("%s", courseType);for (int i = 0; i < c; i++) {if (strcmp(courseType, CourseInfo[i].courseType) == 0) {printf("%s %s %s %d %d %d %f %d\n",CourseInfo[i].courseCode,CourseInfo[i].courseName,CourseInfo[i].courseType,CourseInfo[i].totalPeriod,CourseInfo[i].classPeriod,CourseInfo[i].experiPeriod,CourseInfo[i].creditHour,CourseInfo[i].term);}}printf("数据已经全部显示!\n");}else if (choice == 4) {printf("请输入开课学期:\n");int term = 0;scanf("%d", &term);for (int i = 0; i < c; i++) {if (term == CourseInfo[i].term) {printf("%s %s %s %d %d %d %f %d\n",CourseInfo[i].courseCode,CourseInfo[i].courseName,CourseInfo[i].courseType,CourseInfo[i].totalPeriod,CourseInfo[i].classPeriod,CourseInfo[i].experiPeriod,CourseInfo[i].creditHour,CourseInfo[i].term);}}printf("数据已经全部显示!\n");}else if (choice == 5) {printf("请输入学分:\n");float creditHour = 0.0;scanf("%f", &creditHour);for (int i = 0; i < c; i++) {if (creditHour == CourseInfo[i].creditHour) {printf("%s %s %s %d %d %d %f %d\n",CourseInfo[i].courseCode,CourseInfo[i].courseName,CourseInfo[i].courseType,CourseInfo[i].totalPeriod,CourseInfo[i].classPeriod,CourseInfo[i].experiPeriod,CourseInfo[i].creditHour,CourseInfo[i].term);}}printf("数据已经全部显示!\n");}else {printf("输入错误!!\n");}printf("\n");printf("是否继续查询?(1为是;0为否)\n");scanf("%d", &f);} while (f==1);//***********************************************************************printf("查询完成!!\n");system("pause");}void findStudent(){int i,number,j,f=1;printf("----------------------------------------------\n");printf("学生查询:\n");do{printf("请输入学生学号(例0001):\n");scanf("%d", &number);for (i = 0; i < n; i++){if (number == StuCourInfo[i].stuNo){printf("-学号:%05d\t已选课程编号:", StuCourInfo[i].stuNo);for (j = 0; j != LEN; j++){printf("\t-%s", StuCourInfo[i].courseCode[j]);}printf("\n");break;}}printf("数据已经全部显示!\n");printf("是否继续查询?(1为是;0为否)\n");scanf("%d", &f);} while (f==1);printf("查询完成!!\n");system("pause");}void exitSys(){system("cls");//清屏int h;//控制是否确认退出 printf("即将退出,确认请按1,取消请按0\n");scanf("%d", &h);if (h == 1){t = 0;//t是main函数中while函数是否继续执行的控制条件,是一个全局变量,程序开头已经定义并且赋值位 1printf("成功退出,感谢使用!\n");}if (h == 0){printf("退出已取消!\n");system("pause");}}int main(){select();return 0;}

5、实验报告如下: