Realization of C language student course selection system

Student elective course system design

1. Demand analysis

    The system works in a menu mode, so it is necessary to provide a keyboard selection menu to realize function selection; since the course information is saved in files, it is necessary to provide file input and output operations; because it is necessary to browse information, it is necessary to provide a display function; to realize the query function , so a search operation is provided.

2. Overall design

   The whole system can be designed as information input module, information query module and information browsing module.

3. Detailed design

   The data structure adopts the structure body, and here the course information structure body and the student course selection information structure body are used.

 Struct

{

  Char courseCode[10]; //course number

  Char courseName[20]; //course name

  Char courseType[10]; //course type

  Int totalPeriod; //Total class hours

  Int classPeriod; //Teaching hours

  Int experiPeriod; // computer learning hours

  Float creditHour; //Credit

  Int term; //start term

}CourseInfo[N]; //course information structure

Struct

{

  Int stuNo; //student number;

  Char courseCode[10]; //course number

}StuCourInfo[N]; //Student course selection information structure

(1) Information input module

  Input course information and student course selection information from the keyboard, and write them into files. (fwrite, fprintf)

(2) Information browsing module

  Course information is displayed on split screens, with 10 course records per screen, press any key to continue. Read data from the file (fread, fscanf), and then display.

(3) Information query module

   Select the query field through the menu, and you can search the course information file according to the course number, course name, course nature, semester, and credits. The search algorithm can choose basic search, binary search and other algorithms.

 1. First, create a class.txt file and a student.txt file in the project folder (the folder at the same level as the .c file), and save them as system data files.

 2. When running the system for the first time, it is recommended to select the option to add course and student data first, because there is no data in the data file.

3. The maximum number of elective courses in this system is within 15, and those beyond that will not be counted.

4. The source code is as follows:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>//需要用到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];	//课程编号;001
	char courseName[20];	//课程名称;大学英语
	char courseType[10];	//课程类型;必修
	int totalPeriod;		//总学时;60
	int classPeriod;		//授课学时;40
	int experiPeriod;		//上机学时;20
	float creditHour;		//学分;4
	int 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 < LEN-1; j++)
		{
			fscanf(fp1, "%s ", &StuCourInfo[i].courseCode[j]);
		}
		fscanf(fp1,"%s \n", &StuCourInfo[i].courseCode[j]);
		n++;
		i++;
	}
	fclose(fp1); //关闭文件
	printf("当前课程数为:%d(默认为1)\n",c);
	printf("当前人数为:%d(默认为1)\n", n);
	system("pause");
}
void select() 
{
	int num;//num是菜单选项 
	readInfo();//初始化程序,读取数据文件。
	while (t)//t是全局变量,用tuichu函数来控制循环是否继续 
	{
		system("cls");  //清屏
		menu();//输出主菜单界面 
		printf("您好,请输入菜单编号:");
		scanf("%d", &num);
		switch (num)
		{
		case 1: help(); break;
		case 2: increaseClass(); break;
		case 3: increaseStudent(); break;
		case 4: classDisplay(); break;
		case 5: studentDisplay(); break;
		case 6: find(); break;  //进入后选择findStudent()学生查询还是findClass()课程查询。
		case 0: exitSys(); break;
		default:printf("输入有误,请重新输入!");
		}
	}
	system("pause");
}
void help()
{
	system("cls");  //清屏
	printf("\n这是一个学生选修课程系统,为了帮助您更快的了解使用它,请先仔细阅读以下注意事项:\n");
	printf("\n                  注意事项:\n ");
	printf("\n       1、请根据提示进行操作!\n");
	printf("\n       2、初次使用请先选择增加学生信息!\n");
	printf("\n       3、修改或者增加学生信息后会自动保存,请放心!\n");
	printf("\n       5、若您之前使用过,下次进入系统将会自动读取文件信息!\n");
	printf("\n       6、在添加学生时,用两个字符代表不同的性别,比如男用‘M’代替,女用‘W’代替!\n");
	printf("\n       7、保存或者刷新时,系统会在源程序“studentClass.c”的相同目录建立一个.txt文件来保存学生信息,您可以查看该文件,\n但非专业人员不要轻易改动,否则会造成刷新数据异常或刷新失败!\n");
	printf("\n       8、学生信息包括:学号、已选修的课程号!\n");
	printf("\n       9、课程信息包括:课程编号,课程名称,课程类型,总学时,授课学时,上机学时,学分,开课学期!\n");
	printf("\n       10、使用遇到任何问题请与开发人员联系!\n");
	printf("\n       11、最后感谢您的使用!\n");
	system("pause");
}
void increaseClass()
{
	system("cls");  //清屏
	int i = c, j, flag;  //i表示增加课程数
	printf("\n请输入增加科目数:\n");
	scanf("%d",&M);
	if (M > 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.txt
	if (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 < c; i++)
		{
			//if (fwrite(&CourseInfo[i], sizeof(struct Class), c, fp) != 1)
			//    printf("保存失败!!\n");
			fputs(CourseInfo[i].courseCode, fp);//将CourseInfo[i].courseCode取出来的数据赋给fp指针,并写到文件里
			fputs(" ", fp);
			fputs(CourseInfo[i].courseName, fp);
			fputs(" ", fp);
			fputs(CourseInfo[i].courseType, fp);
			fputs(" ", fp);

			char strTotalPeriod[10];
			sprintf(strTotalPeriod, "%d", CourseInfo[i].totalPeriod);//将int型转换为字符串
			fputs(strTotalPeriod, fp);//将转换后的字符串写入文件
			fputs(" ", fp);

			char strClassPeriod[10];
			sprintf(strClassPeriod,"%d", CourseInfo[i].classPeriod);
			fputs(strClassPeriod, fp);
			fputs(" ", fp);

			char strExperiPeriod[10];
			sprintf(strExperiPeriod,"%d", CourseInfo[i].experiPeriod);
			fputs(strExperiPeriod, fp);
			fputs(" ", fp);

			char strCreditHour[10];
			sprintf(strCreditHour, "%.1f", CourseInfo[i].creditHour);
			fputs(strCreditHour, fp);
			fputs(" ", fp);

			char strTerm[10];
			sprintf(strTerm,"%d" ,CourseInfo[i].term);
			fputs(strTerm, fp);
			fputs("\n", fp);
		}
		M = 0;//添加课程清零
	}
	//printf("请输入文件名:\n");
	//scanf("%s", filename);

	fclose(fp);
	printf("保存成功!!\n");

}
void increaseStudent()
{
	system("cls");  //清屏
	int i = n, j, flag,x=0;  //i表示增加学生人数,x表示学生选课数
	printf("\n请输入增加学生人数:\n");
	scanf("%d", &m);
	if (m > 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; i++)
	{
		printf("%d", i + 1);
		printf("-学号:%05d\t已选课程编号:", StuCourInfo[i].stuNo);

		for (j = 0; j!=LEN; j++)
		{
			printf("\t-%s",StuCourInfo[i].courseCode[j]);
		}
		printf("\n");
	}
	printf("展示完成!!\n");
	printf("----------------------------------------------\n");
	system("pause");
}
void find()
{
	system("cls");  //清屏
	int flag;
	printf("\n----------------------------------------------\n");
	printf("请选择查询方向:\n");
	printf("----》1、课程信息查询\n");
	printf("----》2、学生信息查询\n");
	scanf("%d",&flag);
	printf("----------------------------------------------\n");
	if (flag == 1)
		findClass();
	else
		findStudent();
}
void findClass()
{
	int f = 1;
	printf("----------------------------------------------\n");
	printf("课程查询:\n");
	//***********************************************************************
	do
	{
		printf("1-->根据课程编号查询课程\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函数是否继续执行的控制条件,是一个全局变量,程序开头已经定义并且赋值位 1
		printf("成功退出,感谢使用!\n");
	}
	if (h == 0)
	{
		printf("退出已取消!\n");
		system("pause");
	}
}

int main()
{
	select();
	return 0;
}

 5. The experimental report is as follows:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_53127029/article/details/128510071