C语言--课程管理信息系统

C语言--课程管理信息系统,第1张

课程管理系统
  • 项目要求
  • 函数调用说明
  • 一.设定结构体
  • 二.主函数:
  • 三.录入信息
  • 四.浏览信息
  • 五.查询信息
  • 六.修改信息
  • 七.删除信息
  • 八.对文件的 *** 作
  • 完整代码
  • 代码运行检测及结果

项目要求

课程管理系统
功能:假定有 n 门课程,每门课程有课程编号,课程名称,总学时,学分,开课学期
等信息。试设计一课程管理系统,使之能提供以下功能:
1 对课程信息的录入、修改、删除功能;
2 按课程名排序后浏览;
3 按课程查询、按学分查询;

函数调用说明

一.设定结构体

代码如下:

struct info
{
int number;//课程编号
char name[100];//课程名称
int hours;//总学时
int credit;//学分
int semester;// 开课学期
bool flag;//数据有效标记,
};

这个结构体是用以保存数据,由整型变量 number 存储课程编号;大小为 100 字节的字符数组 name 存储课程名称;由整型变量 hours 存储总学时;由整型变量 credit 存储学分;由整型变量 semester 存储开课学期;由布尔整型变量 flag 存储数据有效标记。

还有以下一些实现功能的结构体:

struct info temp;//临时中转
struct info a[20];//数据存储
struct info newdata; //modify 中,修改的数据存储
struct info original;//del 中,删除数据的判据
二.主函数:

代码如下:

int main(void)//true
{
	long long t = 0;
	FILE* fp;
	if ((fp = fopen("info.dat", "rb+")) != NULL)
	{
		fpos_t pos;//定义pos
		fgetpos(fp, &pos);//获取文件指针,写入pos
		fseek(fp, 0, SEEK_END);//文件指针指向末尾
		t = ftell(fp);//获取文件指针到文件头部的字节大小
		fsetpos(fp, &pos);//文件指针还原
		fclose(fp);//释放文件
	}
	n = t / size;
	//以上实现了有效数据条数n的获取
	printf("有效数据:%d条\n", n);
	char c;//选项代码
	while (1)
	{
		printf("\n\n\n\n");
		printf(" student course management system \n");
		printf("-----------------------------------------------------------------");
		printf("\n\n");
		printf(" 1 录入信息 2 浏览所有信息(排序后) 3 查询信息(名称) \n");
		printf(" 4 修改信息 5 删除信息 6 查询信息(学分) \n");
		printf(" 0 exit system \n");
		printf(" \n\n");
		printf("------------------------------------------------------------------");
		printf("\n please select:");
		c = getchar();
		switch (c)
		{
			case '0'://exit system
			{
				return 0;
			}
			case '1':
			{
				input();//1 录入信息
				getchar();
				break;
			}
			case '2':
			{
				look();//2 浏览所有信息(排序后)
				getchar();
				break;
			}
			case '3':
			{
				QueryName();//3 查询信息(名称)
				getchar();
				break;
			}
			case '4':
			{
				modify();//4 修改信息
				getchar();
				break;
			}
			case '5':
			{
				getchar();
				del();//5 删除信息
				getchar();//防止功能失效
				break;
			}
			case '6':
			{
				QueryCredit();//6 查询信息(学分)
				getchar();
				break;
			}
			default:
			{
				getchar();
				printf("\ninput error,please try again:\n");
				break;
			}
		} 
	}
	return 0;
}
  • 函数的原型声明:int main(void)
  • 函数功能及参数说明
    这个函数是整个程序的 main 函数,用于显示主菜单与用户交互,并依据用户的选择
    调用不同的函数来实现具体的功能。这个函数没有返回值,没有传递参数。
  • 函数中使用的关键变量说明
  1. Int size:用于表示一条数据所占用的字节数,即 struct info 类型所占用的空间。
  2. long long t:用于表示文件的大小,从与 int size 一起确定有效数据 n 的值。
  3. char c:用于存储用户的选项编号。
  4. int n:用于存储有效数据的条数
三.录入信息

代码如下:

void input(void)//1 录入信息 true
{
	char ch;
	while (1)
	{
		printf("课程编号");
		scanf("%d", &temp.number);
		printf("课程名称");
		scanf("%s", &temp.name);
		printf("总学时");
		scanf("%d", &temp.hours);
		printf("学分");
		scanf("%d", &temp.credit);
		printf("开课学期");
		scanf("%d", &temp.semester);
		temp.flag = 1;
		n++;//有效数据增加1条
		copy3(n - 1);//由temp中写入数组中
		getchar();//接受换行符
		printf("是否继续录入?[y/n]\n");
		ch = getchar();
		if (ch == 'n' || ch == 'N')
		break;
	}
		writeToFile();//统一写入文件info.dat
}
四.浏览信息
void look(void)//2 浏览所有信息(排序后) true 
{
	load();
	//sort
	for (int i = 0; i < n - 1; i++) {
	int k = i;// 最小元素的下标
	for (int j = i + 1; j < n; j++)
	if (strcmp(a[k].name, a[j].name) > 0)//从小到大排序
	k = j;//如果a[k]>a[j],即有元素比我们认为的最小元素更小,那就更新最小元素的下标
	if (k != i)
	{//等效于三步交换法
		copy1(i);
		copy2(i, k);
		copy3(k);
	} 
}
display_header();//表头
display_all();//内容
display_end();//表尾
}
五.查询信息
  1. 查询名称
void QueryName(void)//3 查询信息(名称)true
{
	char ch;
	char CName[100];//用于存储课程的名称
	while (1)
	{
		printf("请输入课程名称:");
		scanf("%s", CName);
		getchar();
		load();
		display_header();
		for (int i = 0; i < n; i++)
		{
		// printf("%d\n",i);
		if (strcmp(a[i].name, CName) == 0)
		{
			printf("ture.\n");
			copy1(i);
			display();
		} 
	}
	display_end();
	printf("是否继续查询?[y/n]\n");
	scanf("%c", &ch);
	if (ch == 'n' || ch == 'N')
		break;
	} 
}
  1. 查询学分
void QueryCredit(void)//6 查询信息(学分) true
{
	char ch;
	int mark;//用于存储课程的学分
	while (1)
	{
		printf("请输入课程学分:");
		scanf("%d", &mark);
		getchar();
		load();
		display_header();
		for (int i = 0; i < n; i++)
		{
		if (mark == a[i].credit)
		{
			copy1(i);
			display();
		} 
	}
	display_end();
	printf("是否继续查询?[y/n]\n");
	ch = getchar();
	if (ch == 'n' || ch == 'N')
		break;
	} 
}
六.修改信息
void modify(void)//4 修改信息
{
	struct info newdata;//modify中修改的数据存储
	int num;
	load();//读原文件info.dat
	look();
	printf("用课程编号来确定修改的数据行:");
	scanf("%d", &num);
	getchar();
	printf("\n\n");
	printf(" student course info \n");
	printf("------------------------------------------------------------------\n");
	printf("你想修改什么?\n");
	printf("1.课程名称 2.总学时 3.学分\n");
	printf("4.开课学期\n");
	printf("------------------------------------------------------------------");
	printf("\n please select:");
	char c = getchar();
	while (c > '4' || c < '1')
	{
		printf("\n输入错误,重试");
		c = getchar();
	}
	getchar();
	switch (c)
	{
		case '1'://1.课程名称
	{
	printf("请输入新名称:");
	gets(newdata.name);
	for (int i = 0; i < n; i++)
		if (a[i].number == num)
			strcpy(a[i].name, newdata.name);
	break;
	}
	case '2'://2.总学时
	{
		printf("请输入新总学时:");
		scanf("%d", &newdata.hours);
		for (int i = 0; i < n; i++)
			if (a[i].number == num)
				a[i].hours = newdata.hours;
	break;
	}
	case '3'://3.学分
	{
		printf("请输入新学分:");
		scanf("%d", &newdata.credit);
		for (int i = 0; i < n; i++)
			if (a[i].number == num)
			a[i].credit = newdata.credit;
	break;
	}
	case '4'://4.开课学期
	{
		printf("请输入新开课学期:");
		scanf("%d", &newdata.semester);
		for (int i = 0; i < n; i++)
			if (a[i].number == num)
				a[i].semester = newdata.semester;
	break;
	}
	}
writeToFile();
}
七.删除信息
void del(void)//5删除信息
{
	struct info original;//删除数据的判据
	long long t = 0;
	FILE* ftemp;
	load();//读原文件info.dat
	printf("\n\n");
	printf(" student course info \n");
	printf("------------------------------------------------------------------\n");
	printf("你想通过哪种方式来查找需要删除的记录?\n");
	printf("1.课程编号 2.课程名称 3.总学时\n");
	printf("4.学分 5.开课学期\n");
	printf("-----------------------------------------------------------------");
	printf("\n please select:");
	char c = getchar();
	while (c > '5' || c < '1')
	{
		printf("\n输入错误,重试");
		c = getchar();
	}
	getchar();
	switch (c)
	{
		case '1'://1.课程编号
		{
			printf("请输入课程编号:");
			scanf("%d", &original.number);
			for (int i = 0; i < n; i++)
				if (a[i].number == original.number)
					a[i].flag = false;
			break;
		}
		case '2'://2.课程名称
		{
			printf("请输入课程名称:");
			gets(original.name);
			for (int i = 0; i < n; i++)
				if (strcmp(a[i].name, original.name) == 0)
					a[i].flag = false;
			break;
		}
		case '3'://3.总学时
		{
			printf("请输入总学时:");
			scanf("%d", &original.hours);
			for (int i = 0; i < n; i++)
				if (a[i].hours == original.hours)
					a[i].flag = false;
			break;
		}
		case '4'://4.学分
		{
			printf("请输入学分:");
			scanf("%d", &original.credit);
			for (int i = 0; i < n; i++)
				if (a[i].credit == original.credit)
					a[i].flag = false;
			break;
		}
		case '5'://5.开课学期
		{
			printf("请输入开课学期:");
			scanf("%d", &original.semester);
			for (int i = 0; i < n; i++)
				if (a[i].semester == original.semester)
					a[i].flag = false;
			break;
		}}
	if ((ftemp = fopen("temporary.dat", "wb")) == NULL)//写打开临时文件temporary.dat
	{
		printf("Open the file failure...\n");
		exit(EXIT_SUCCESS);
	}
	for (int i = 0; i < n; i++)
		if (a[i].flag == false)
			continue;
		else
			fwrite(&a[i], size, 1, ftemp);//不是则将这写入临时文件temporary.dat
			fpos_t pos;//定义pos
			fgetpos(ftemp, &pos);//获取文件指针,写入pos
			fseek(ftemp, 0, SEEK_END);//文件指针指向末尾
			t = ftell(ftemp);//获取文件指针到文件头部的字节大小
			fsetpos(ftemp, &pos);//文件指针还原
			fclose(ftemp);
			n = t / size;//因为文件的变动,更新n的值
			
	int back1 = remove("info.dat");
	int back2 = rename("temporary.dat", "info.dat");//将临时文件名改为原文件名
	if (!back1 && !back2)
		printf("成功!\n");
	else printf("%d %d\n失败!\n", back1, back2);
}
八.对文件的 *** 作
void writeToFile(void)//true
{
	FILE* fp;
	if ((fp = fopen("info.dat", "wb")) == NULL)
	{
		printf("无法打开此文件\n");
		exit(EXIT_SUCCESS);
	}
	for (int i = 0; i < n; i++)
	{ 
		if (fwrite(&a[i], size, 1, fp) != 1)
			{
				printf("file write error.\n");
			} 
	}
	fclose(fp);
}
完整代码
//main.cpp
/*
课程管理系统:
功能:假定有n门课程,每门课程有课程编号,课程名称,总学时,学分,开课学期
等信息。试设计一课程管理系统,使之能提供以下功能:
1对课程信息的录入、修改、删除功能;
2按课程名排序后浏览;
3按课程查询、按学分查询;
*/
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
struct info
{
	int number;//课程编号
	char name[100];//课程名称
	int hours;//总学时
	int credit;//学分
	int semester;//开课学期
	bool flag;//数据有效标记
} temp;//临时中转

struct info a[20];//数据存储
int size = sizeof(struct info);//结构体单条数据占用空间
int n = 0;//有效数据个数
void input();//1 录入信息
void look();//2 浏览所有信息(排序后)
void QueryName();//3 查询信息(名称)
void modify();//4 修改信息
void del();//5 删除信息
void QueryCredit();//6 查询信息(学分)
void writeToFile();
void load();
//copy类的函数主要用于数据的排序
void copy1(int i);
void copy2(int i, int j);
void copy3(int i);
void display_all();//显示所有的有效数据
void display(); //特定行的数据
void display_header();//表头
void display_end();//表尾
int main(void)//true
{
	long long t = 0;
	FILE* fp;
	if ((fp = fopen("info.dat", "rb+")) != NULL)
	{
		fpos_t pos;//定义pos
		fgetpos(fp, &pos);//获取文件指针,写入pos
		fseek(fp, 0, SEEK_END);//文件指针指向末尾
		t = ftell(fp);//获取文件指针到文件头部的字节大小
		fsetpos(fp, &pos);//文件指针还原
		fclose(fp);//释放文件
	}
	n = t / size;
	//以上实现了有效数据条数n的获取
	printf("有效数据:%d条\n", n);
	char c;//选项代码
	while (1)
	{
		printf("\n\n\n\n");
		printf(" student course management system \n");
		printf("-----------------------------------------------------------------");
		printf("\n\n");
		printf(" 1 录入信息 2 浏览所有信息(排序后) 3 查询信息(名称) \n");
		printf(" 4 修改信息 5 删除信息 6 查询信息(学分) \n");
		printf(" 0 exit system \n");
		printf(" \n\n");
		printf("------------------------------------------------------------------");
		printf("\n please select:");
		c = getchar();
		switch (c)
		{
			case '0'://exit system
			{
				return 0;
			}
			case '1':
			{
				input();//1 录入信息
				getchar();
				break;
			}
			case '2':
			{
				look();//2 浏览所有信息(排序后)
				getchar();
				break;
			}
			case '3':
			{
				QueryName();//3 查询信息(名称)
				getchar();
				break;
			}
			case '4':
			{
				modify();//4 修改信息
				getchar();
				break;
			}
			case '5':
			{
				getchar();
				del();//5 删除信息
				getchar();//防止功能失效
				break;
			}
			case '6':
			{
				QueryCredit();//6 查询信息(学分)
				getchar();
				break;
			}
			default:
			{
				getchar();
				printf("\ninput error,please try again:\n");
				break;
			}
		} 
	}
	return 0;
}

void input(void)//1 录入信息 true
{
	char ch;
	while (1)
	{
		printf("课程编号");
		scanf("%d", &temp.number);
		printf("课程名称");
		scanf("%s", &temp.name);
		printf("总学时");
		scanf("%d", &temp.hours);
		printf("学分");
		scanf("%d", &temp.credit);
		printf("开课学期");
		scanf("%d", &temp.semester);
		temp.flag = 1;
		n++;//有效数据增加1条
		copy3(n - 1);//由temp中写入数组中
		getchar();//接受换行符
		printf("是否继续录入?[y/n]\n");
		ch = getchar();
		if (ch == 'n' || ch == 'N')
		break;
	}
		writeToFile();//统一写入文件info.dat
}
void look(void)//2 浏览所有信息(排序后) true 
{
	load();
	//sort
	for (int i = 0; i < n - 1; i++) {
	int k = i;// 最小元素的下标
	for (int j = i + 1; j < n; j++)
	if (strcmp(a[k].name, a[j].name) > 0)//从小到大排序
	k = j;//如果a[k]>a[j],即有元素比我们认为的最小元素更小,那就更新最小元素的下标
	if (k != i)
	{//等效于三步交换法
		copy1(i);
		copy2(i, k);
		copy3(k);
	} 
}
display_header();//表头
display_all();//内容
display_end();//表尾
}

void QueryName(void)//3 查询信息(名称)true
{
	char ch;
	char CName[100];//用于存储课程的名称
	while (1)
	{
		printf("请输入课程名称:");
		scanf("%s", CName);
		getchar();
		load();
		display_header();
		for (int i = 0; i < n; i++)
		{
		// printf("%d\n",i);
		if (strcmp(a[i].name, CName) == 0)
		{
			printf("ture.\n");
			copy1(i);
			display();
		} 
	}
	display_end();
	printf("是否继续查询?[y/n]\n");
	scanf("%c", &ch);
	if (ch == 'n' || ch == 'N')
		break;
	} 
}

void modify(void)//4 修改信息
{
	struct info newdata;//modify中修改的数据存储
	int num;
	load();//读原文件info.dat
	look();
	printf("用课程编号来确定修改的数据行:");
	scanf("%d", &num);
	getchar();
	printf("\n\n");
	printf(" student course info \n");
	printf("------------------------------------------------------------------\n");
	printf("你想修改什么?\n");
	printf("1.课程名称 2.总学时 3.学分\n");
	printf("4.开课学期\n");
	printf("------------------------------------------------------------------");
	printf("\n please select:");
	char c = getchar();
	while (c > '4' || c < '1')
	{
		printf("\n输入错误,重试");
		c = getchar();
	}
	getchar();
	switch (c)
	{
		case '1'://1.课程名称
	{
	printf("请输入新名称:");
	gets(newdata.name);
	for (int i = 0; i < n; i++)
		if (a[i].number == num)
			strcpy(a[i].name, newdata.name);
	break;
	}
	case '2'://2.总学时
	{
		printf("请输入新总学时:");
		scanf("%d", &newdata.hours);
		for (int i = 0; i < n; i++)
			if (a[i].number == num)
				a[i].hours = newdata.hours;
	break;
	}
	case '3'://3.学分
	{
		printf("请输入新学分:");
		scanf("%d", &newdata.credit);
		for (int i = 0; i < n; i++)
			if (a[i].number == num)
			a[i].credit = newdata.credit;
	break;
	}
	case '4'://4.开课学期
	{
		printf("请输入新开课学期:");
		scanf("%d", &newdata.semester);
		for (int i = 0; i < n; i++)
			if (a[i].number == num)
				a[i].semester = newdata.semester;
	break;
	}
	}
writeToFile();
}

void del(void)//5删除信息
{
	struct info original;//删除数据的判据
	long long t = 0;
	FILE* ftemp;
	load();//读原文件info.dat
	printf("\n\n");
	printf(" student course info \n");
	printf("------------------------------------------------------------------\n");
	printf("你想通过哪种方式来查找需要删除的记录?\n");
	printf("1.课程编号 2.课程名称 3.总学时\n");
	printf("4.学分 5.开课学期\n");
	printf("-----------------------------------------------------------------");
	printf("\n please select:");
	char c = getchar();
	while (c > '5' || c < '1')
	{
		printf("\n输入错误,重试");
		c = getchar();
	}
	getchar();
	switch (c)
	{
		case '1'://1.课程编号
		{
			printf("请输入课程编号:");
			scanf("%d", &original.number);
			for (int i = 0; i < n; i++)
				if (a[i].number == original.number)
					a[i].flag = false;
			break;
		}
		case '2'://2.课程名称
		{
			printf("请输入课程名称:");
			gets(original.name);
			for (int i = 0; i < n; i++)
				if (strcmp(a[i].name, original.name) == 0)
					a[i].flag = false;
			break;
		}
		case '3'://3.总学时
		{
			printf("请输入总学时:");
			scanf("%d", &original.hours);
			for (int i = 0; i < n; i++)
				if (a[i].hours == original.hours)
					a[i].flag = false;
			break;
		}
		case '4'://4.学分
		{
			printf("请输入学分:");
			scanf("%d", &original.credit);
			for (int i = 0; i < n; i++)
				if (a[i].credit == original.credit)
					a[i].flag = false;
			break;
		}
		case '5'://5.开课学期
		{
			printf("请输入开课学期:");
			scanf("%d", &original.semester);
			for (int i = 0; i < n; i++)
				if (a[i].semester == original.semester)
					a[i].flag = false;
			break;
		}}
	if ((ftemp = fopen("temporary.dat", "wb")) == NULL)//写打开临时文件temporary.dat
	{
		printf("Open the file failure...\n");
		exit(EXIT_SUCCESS);
	}
	for (int i = 0; i < n; i++)
		if (a[i].flag == false)
			continue;
		else
			fwrite(&a[i], size, 1, ftemp);//不是则将这写入临时文件temporary.dat
			fpos_t pos;//定义pos
			fgetpos(ftemp, &pos);//获取文件指针,写入pos
			fseek(ftemp, 0, SEEK_END);//文件指针指向末尾
			t = ftell(ftemp);//获取文件指针到文件头部的字节大小
			fsetpos(ftemp, &pos);//文件指针还原
			fclose(ftemp);
			n = t / size;//因为文件的变动,更新n的值
			
	int back1 = remove("info.dat");
	int back2 = rename("temporary.dat", "info.dat");//将临时文件名改为原文件名
	if (!back1 && !back2)
		printf("成功!\n");
	else printf("%d %d\n失败!\n", back1, back2);
}

void QueryCredit(void)//6 查询信息(学分) true
{
	char ch;
	int mark;//用于存储课程的学分
	while (1)
	{
		printf("请输入课程学分:");
		scanf("%d", &mark);
		getchar();
		load();
		display_header();
		for (int i = 0; i < n; i++)
		{
		if (mark == a[i].credit)
		{
			copy1(i);
			display();
		} 
	}
	display_end();
	printf("是否继续查询?[y/n]\n");
	ch = getchar();
	if (ch == 'n' || ch == 'N')
		break;
	} 
}

void writeToFile(void)//true
{
	FILE* fp;
	if ((fp = fopen("info.dat", "wb")) == NULL)
	{
		printf("无法打开此文件\n");
		exit(EXIT_SUCCESS);
	}
	for (int i = 0; i < n; i++)
	{ 
		if (fwrite(&a[i], size, 1, fp) != 1)
			{
				printf("file write error.\n");
			} 
	}
	fclose(fp);
}

void copy1(int i)//第一步
{
	temp.number = a[i].number;
	strcpy(temp.name, a[i].name);
	temp.hours = a[i].hours;
	temp.credit = a[i].credit;
	temp.semester = a[i].semester;
	temp.flag = a[i].flag;
}
void copy2(int i, int j)//第二步
{
	a[i].number = a[j].number;
	strcpy(a[i].name, a[j].name);
	a[i].hours = a[j].hours;
	a[i].credit = a[j].credit;
	a[i].semester = a[j].semester;
	a[i].flag = a[j].flag;
}
void copy3(int i)//第三步
{
	a[i].number = temp.number;
	strcpy(a[i].name, temp.name);
	a[i].hours = temp.hours;
	a[i].credit = temp.credit;
	a[i].semester = temp.semester;
	a[i].flag = temp.flag;
}
void load(void)//true
{
	FILE* fp;
	if ((fp = fopen("info.dat", "rb")) == NULL)
	{
		printf("无法打开此文件\n");
		exit(EXIT_SUCCESS);
	}
	for (int i = 0; i < n; i++)
	{
		if (fread(&a[i], size, 1, fp) != 1)
		{
			if (feof(fp))
			{
				fclose(fp);
				printf("file end.\n");
			}
			else
			printf("file read error.\n");
		} 
	}
	fclose(fp);
}

void display_header(void)//true
{
	printf("\n\n");
	printf(" student course info \n");
	printf("------------------------------------------------------------------");
	printf("\n");
	printf("课程编号 课程名称 总学时 学分 开课学期 \n");
	printf("------------------------------------------------------------------\n");
}

void display_end(void)//true
{
	printf("------------------------------------------------------------------\n");
}

void display_all(void)//true
{
	for (int i = 0; i < n; i++)
	printf("%8d%16s%14d%14d%14d\n", a[i].number, a[i].name, a[i].hours, 
	a[i].credit, a[i].semester);
}
void display(void)//true
{
	printf("%8d%16s%14d%14d%14d\n", temp.number, temp.name, temp.hours, 
	temp.credit, temp.semester);
}
代码运行检测及结果







欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1323412.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-12
下一篇2022-06-12

发表评论

登录后才能评论

评论列表(0条)

    保存