C语言实现学生管理系统

C语言实现-学生管理系统

程序员的必经之路吧,学生管理系统。在制作过程中体会到了编写一个具体可用的软件而要做的工作,无论是编写前的准备,还是编写过程中每个细节的处理,都让我理解了这份工作是个什么样子。程序并不是抬手就来,一个软件要完整,同时还要将每个功能部分区分开,所以在编写之前一定要先规划清楚,这是一项工程。逻辑要严密,编程完全就是对逻辑思维的考验,大大小小的函数、语句都是靠逻辑连接起来的。基础知识要扎实,在我现在这个阶段,经常会遇到为干掉bug而苦思半天,在逻辑上寻觅没有出口,其实只是对用法不了解,上课时认为那种不太常考的东西不用太费心,只要把主要的知识记住就行,但事实上每个知识点都是有用的,接下来使用数组,动态数组,单向链表,文件操作等来实现C语言:学生管理系统。
这里使用的是VS2019,如果你使用的是CodeBlocks或DEV C++等请先把第一行注释掉。

对学生信息管理系统,要求完成以下基本任务:

1.改写程序为良好程序风格(文档注释,函数注释,语句注释)。
2.将功能补充完全(基于文件处理,完成刷新和保存功能)。
3.将学生信息改为更好的数据组织,而非离散形式(结构体)。
4.可将程序中的不足(如数据验证)等根据自己的能力与理解完成。
5.用使用C语言做一个学生信息管理系统,我的想法是先把需要的一些变量封装在结构体中,然后结合以前学过的数据结构知识(链表),做一些增删查改的操作,并将其保存在文件中。

群内有各种学习资料,欢迎大家一起来学习哦~
如果大家遇到什么问题也欢迎大家进群讨论哦~

qq群:759252814

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include

/**********************保存学生信息的结构体**********************/

typedef struct Student       //使用typedef为struct Student起别名为XIN
{
	char Student_id[30];     //学生编号
	char name[30];           //学生姓名
	int age;                 //学生年龄
	char sex[5];             //学生性别
	float Ascore;            //语文分数
	float Bscore;            //数学分数 
	float Cscore;            //英语分数
	float Count;             //三科总分
	struct Student* next;    //指向下一个地址
}XIN;

int color(int n);										 //字体颜色 
void gotoxy(int x, int y);								 //字体位置 
void Aframe();											 //边框 1号 蓝 紫
void Bframe();										     //边框 2号 蓝 红
void Main_interface();                                   //主界面
void Write_in();                                         //输入信息
void Output();                                           //输出信息
void Lookup();                                           //查找信息
void Sort();                                             //成绩排序
void Delete();                                           //删除信息

/**********************主界面**********************/

void Main_interface()
{
	system("cls");                           //每次调用 Main_interface() 函数时调用一次 system("cls") 进行清屏函数
	gotoxy(19, 2);                           //字符打印位置,如最左上角的坐标为 0.0
	color(13);                               //接下来打印的字体颜色如:10为绿色,13为紫色
	printf("===========学 生 管 理 系 统 菜 单===========\n");
	Aframe();                   //使用边框 1号 
	color(2);
	gotoxy(60, 1);
	printf("欢迎您的使用! ^_^");
	color(14);
	gotoxy(24, 6);
	color(9);
	printf("=======请选择功能列表=======\n");
	color(10);
	gotoxy(12, 8);
	printf("1.添加学生信息\n");
	gotoxy(12, 10);
	color(14);
	printf("2.查看学生信息n");
	gotoxy(12, 12);
	color(13);
	printf("3.查找学生信息\n");
	gotoxy(12, 14);
	color(11);
	printf("4.按成绩排序\n");
	gotoxy(12, 16);
	color(9);
	printf("5.删除学生信息\n");
	color(7);
	gotoxy(12, 18);
	printf("6.退出程序");

label:                       //标签 用于goto语句
	gotoxy(26, 22);
	color(14);
	printf("本程序会自动读取 请选择[ ]\b\b");
	char ch;                 //存放输入的字符
	ch = _getch();           //读取键盘输入的一个字符不显示 \不回显函数
	
	putchar(ch);
	switch (ch)
	{
		case '1':system("cls"); Write_in(); 	    break;      //system("cls"); 清屏函数
		case '2':system("cls"); Output();  		break;
		case '3':system("cls"); Lookup(); 		break;
		case '4':system("cls"); Sort();         break;
		case '5':Delete();   					break;
		case '6':system("cls"); exit(0);   		break;      //exit(0):结束程序返回值为0
		case 27 :system("cls"); exit(0);   		break;      //27为Esc的ASCLL编号
		default:goto label;                     break;      //goto label:无条件跳转至标签 label 处
	};
}
int main(void)
{
	Main_interface();
	return 0;
}

/**********************输入信息**********************/

void Write_in()
{
	FILE* fp;                 //文件指针
	XIN temp;                 //为当前输入内容

	//打开文件并判断是否打开成功或创建成功,ab+是以二进制追加的方式打开,如果找不到该文件则创建一个studentA.datd文件来储存信息,如果也创建失败则报错并结束程序
	if ((fp = fopen("studentA.datd", "ab+")) == NULL)    
	{
		printf("创建文件或添加信息失败! 错误代码:0x001");
		exit(1);
	}
	int count = 0;                  //当前输入的学生人数
	while (TRUE)                    //一直输入信息直到break跳出
	{
		system("cls");
		count++;
		gotoxy(17, 2);
		color(13);
		printf("===========添 加 学 生 信 息 界 面===========\n");
		Aframe();
		gotoxy(10, 6);
		color(10);
		printf("请输入第%d位学生的学号:", count);
		scanf("%s", temp.Student_id);
		if (strcmp(temp.Student_id, "-1") == 0)                 //当学号输入为-1时退出输入,把信息储存到文件并关闭文件
		{
			break;
		}
		gotoxy(10, 8);
		printf("请输入第%d位学生的名字:", count);
		scanf("%s", temp.name);
		gotoxy(10, 10);
		printf("请输入第%d位学生的性别:", count);
		scanf("%s", temp.sex);
		gotoxy(10, 12);
		printf("请输入第%d位学生的年龄:", count);
		scanf("%d", &temp.age);
		gotoxy(10, 14);
		printf("请输入第%d位学生的语文成绩:", count);
		scanf("%f", &temp.Ascore);
		gotoxy(10, 16);
		printf("请输入第%d位学生的数学成绩:", count);
		scanf("%f", &temp.Bscore);
		gotoxy(10, 18);
		printf("请输入第%d位学生的英语成绩:", count);
		scanf("%f", &temp.Cscore);
		temp.Count = temp.Ascore + temp.Bscore + temp.Cscore;
		fwrite(&temp, sizeof(XIN), 1, fp);
		gotoxy(26, 22);
		color(14);
		printf("是否要继续'y'或者'n'[ ]\b\b");
		char ch;
	label:                                 //判断 
		ch = _getch();
		if (ch == 'y' || ch == 'Y')
		{
			printf("\n");
		}
		else if (ch == 'n' || ch == 'N')
		{
			fclose(fp);
			Main_interface();
		}
		else
			goto label;
	}
	fclose(fp);
}

/**********************输出信息**********************/
void Output()
{
	system("cls");
	XIN temp;
	FILE* fp;
	char ch;
	//打开文件并判断是否打开成功,rb是以二进制只读的方式打开,如果找不到则报错并结束程序
	if ((fp = fopen("studentA.datd", "rb")) == NULL)
	{
		printf("打开文件失败,请确定是否创建了该文件! 错误代码:0x002");
		exit(1);
	}
	int i = 1;
	int count = 0;                        //判断是否存文件中读取信息
	fread(&temp, sizeof(XIN), 1, fp);
	while (!feof(fp))                     //feof用检测流上的文件结束符,其返回值有两种情况:如果遇到文件结束,函数值为非零值,否则函数值为0
	{
		system("cls");
		count = 1;
		Aframe();
		gotoxy(19, 2);
		color(13);
		printf("=========== 查 看 信 息 界 面===========\n");
		gotoxy(18, 9);
		color(13);
		printf("学号为:%s\n", temp.Student_id);
		gotoxy(48, 9);
		color(10);
		printf("名字为:%s\n", temp.name);
		gotoxy(18, 12);
		color(9);
		printf("性别为:%s\n", temp.sex);
		gotoxy(48, 12);
		color(13);
		printf("年龄为:%d\n", temp.age);
		gotoxy(18, 15);
		color(13);
		printf("语文为:%.1f\n", temp.Ascore);
		gotoxy(48, 15);
		color(10);
		printf("数学为:%.1f\n", temp.Bscore);
		gotoxy(18, 18);
		color(10);
		printf("英语为:%.1f\n", temp.Cscore);
		gotoxy(48, 18);
		color(9);
		printf("总分为:%.1f\n", temp.Count);
		gotoxy(30, 6);
		color(14);
		printf("第%d位学生的信息", i);
		gotoxy(26, 22);
		color(14);
		printf("本程序会自动读取 请选择[ ]\b\b");
	label:
		ch = _getch();
		if (ch == 80)                 //下键的ASCII编码
			i++;
		else if (ch == 27)
			Main_interface();        //Esc的ASCII编码
		else if (ch == 72)           //上键的ASCII编码
		{
			fseek(fp, -192L, SEEK_CUR); //文件指针在当前位置向后移动192个字节,结构体 struct Student 所占的字节为:96
			i--;
		}
		else
			goto label;
		fread(&temp, sizeof(XIN), 1, fp);
	}
	fclose(fp);
	if (count == 0)                      //如果为0则说明未从文件中读取出内容文件为空
	{
		Bframe();
		gotoxy(19, 2);
		color(13);
		printf("=========== 查 看 信 息 界 面===========\n");
		color(12);
		gotoxy(25, 8);
		printf("没 有 添 加 任 何 信 息 !");
		gotoxy(23, 15);
		color(13);
		printf("按Esc键返回主页面回车键添加 [ ]\b\b");
		char ch;
	label2:
		ch = _getch();
		if (ch == 27)
			Main_interface();
		else if (ch == 13)    //空格键的ASCII编码
			Write_in();
		else
			goto label2;
	}
	else
	{
		gotoxy(24, 22);
		color(10);
		printf("请按Esc返回本程序会自动读取 [ ]\b\b");                          //结束返回                          
	label3:
		ch = _getch();
		if (ch == 27)
			Main_interface();
		else
			goto label3;
	}
}

/**********************查找信息**********************/
void Lookup()
{
	FILE* fp;
	XIN temp;
	char Name[30];
	gotoxy(15, 2);
	color(11);
	printf("=========== 查 找 学 生 信 息 界 面===========\n");
	Bframe();
	color(14);
	gotoxy(20, 8);
	printf("请输入需要找查的学生名字:");
	scanf("%s", Name);
	gotoxy(27, 15);
	color(13);
	printf("按Esc键返回主页面[ ]\b\b");

	if ((fp = fopen("studentA.datd", "rb")) == NULL)
	{
		printf("打开文件失败,请确定是否创建了该文件! 错误代码:0x003");
		exit(1);
	}
	int Count = 0;
	fread(&temp, sizeof(XIN), 1, fp);
	while (!feof(fp))
	{
		system("cls");
		if (strcmp(temp.name, Name) == 0)                         //从文件中读取如果匹配则输出
		{
			Count = 1;
			Aframe();
			gotoxy(15, 2);
			color(13);
			printf("=========== 查 找 学 生 信 息 界 面===========\n");
			gotoxy(18, 9);
			color(13);
			printf("学号为:%s\n", temp.Student_id);
			gotoxy(48, 9);
			color(10);
			printf("名字为:%s\n", temp.name);
			gotoxy(18, 12);
			color(9);
			printf("性别为:%s\n", temp.sex);
			gotoxy(48, 12);
			color(13);
			printf("年龄为:%d\n", temp.age);
			gotoxy(18, 15);
			color(13);
			printf("语文为:%.1f\n", temp.Ascore);
			gotoxy(48, 15);
			color(10);
			printf("数学为:%.1f\n", temp.Bscore);
			gotoxy(18, 18);
			color(10);
			printf("英语为:%.1f\n", temp.Cscore);
			gotoxy(48, 18);
			color(9);
			printf("总分为:%.1f\n", temp.Count);
			gotoxy(30, 6);
			color(14);
			printf("教师“%s”的信息如下", Name);
			gotoxy(30, 22);
			color(14);
			printf("按Esc键退出 [ ]\b\b");
			char ch;
		label:
			ch = _getch();
			if (ch == 27)
			{
				Main_interface();
			}
			else
			{
				goto label;
			}
			break;
		}
		fread(&temp, sizeof(XIN), 1, fp);
	}
	if (Count == 0)
	{
		system("cls");
		gotoxy(15, 2);
		color(11);
		printf("=========== 查 找 学 生 信 息 界 面===========\n");
		Bframe();
		color(12);
		gotoxy(25, 8);
		//printf("                                               ");
		gotoxy(25, 8);
		printf("没有找到该学生的任何信息!");
		gotoxy(27, 13);
		color(13);
		printf("按Esc键返回主页面[ ]\b\b");
		char ch2;
	label2:
		ch2 = _getch();
		if (ch2 == 27)
			Main_interface();
		else
			goto label2;
	}
}

/**********************成绩排序**********************/
void Sort()
{
	FILE* fp;
	XIN temp;
	int Acount = 0;
	int Bcount = 0;
	int NUMBER = 0;        //通过循环统计有多少位学生,并以NUMBER的值创建一个动态数组
	if ((fp = fopen("studentA.datd", "rb")) == NULL)
	{
		printf("打开文件失败,请确定是否创建了该文件! 错误代码:0x004");
		exit(1);
	}
	fread(&temp, sizeof(XIN), 1, fp);
	while (!feof(fp))                     //feof用检测流上的文件结束符,其返回值有两种情况:如果遇到文件结束,函数值为非零值,否则函数值为0
	{
		Acount = 1;
		NUMBER++;
		fread(&temp, sizeof(XIN), 1, fp);
	}
	fclose(fp);

	if (Acount == 0)                      //用于判断文件中是否有信息,如果没有则提示
	{
		Bframe();                         //边框二号
		gotoxy(19, 2);
		color(13);
		printf("=========== 按 成 绩 排 序 界 面 ===========\n");
		color(12);
		gotoxy(25, 8);
		printf("没 有 添 加 任 何 信 息 !");
		gotoxy(23, 14);
		color(13);
		printf("按Esc键返回主页面回车键添加 [ ]\b\b");
		char ch;
	label2:
		ch = _getch();
		if (ch == 27)
			Main_interface();
		else if (ch == 13)    //空格键的ASCII编码
			Write_in();
		else
			goto label2;
	}

	if ((fp = fopen("studentA.datd", "rb")) == NULL)
	{
		printf("打开文件失败,请确定是否创建了该文件! 错误代码:0x005");
		exit(1);
	}
	XIN* information;
	information = (XIN*)malloc(sizeof(XIN) * NUMBER);
	int i = 0;                                //用于动态数组的下标
	fread(&temp, sizeof(XIN), 1, fp);
	while (!feof(fp))                     //feof用检测流上的文件结束符,其返回值有两种情况:如果遇到文件结束,函数值为非零值,否则函数值为0
	{
		strcpy(information[i].Student_id, temp.Student_id);  ////把读取出来的内容赋值给结构体数组information
		strcpy(information[i].name, temp.name);
		strcpy(information[i].sex, temp.sex);
		information[i].age = temp.age;
		information[i].Ascore = temp.Ascore;
		information[i].Bscore = temp.Bscore;
		information[i].Cscore = temp.Cscore;
		information[i].Count = temp.Count;
		fread(&temp, sizeof(XIN), 1, fp);
		i++;
	}
	fclose(fp);
	XIN Temp;
	for (int i = 0; i < NUMBER; i++)
	{
		for (int j = i + 1; j < NUMBER; j++)
		{
			if (information[i].Count < information[j].Count)
			{
				Temp = information[i];
				information[i] = information[j];
				information[j] = Temp;
			}
		}
	}
	for (int i = 0; i < NUMBER; i++)
	{
		system("cls");
		Aframe();
		gotoxy(19, 2);
		color(13);
		printf("=========== 查 看 信 息 界 面===========\n");
		gotoxy(18, 9);
		color(13);
		printf("学号为:%s\n", information[i].Student_id);
		gotoxy(48, 9);
		color(10);
		printf("名字为:%s\n", information[i].name);
		gotoxy(18, 12);
		color(9);
		printf("性别为:%s\n", information[i].sex);
		gotoxy(48, 12);
		color(13);
		printf("年龄为:%d\n", information[i].age);
		gotoxy(18, 15);
		color(13);
		printf("语文为:%.1f\n", information[i].Ascore);
		gotoxy(48, 15);
		color(10);
		printf("数学为:%.1f\n", information[i].Bscore);
		gotoxy(18, 18);
		color(10);
		printf("英语为:%.1f\n", information[i].Cscore);
		gotoxy(48, 18);
		color(9);
		printf("总分为:%.1f\n", information[i].Count);
		gotoxy(30, 6);
		color(14);
		printf("第%d位学生的信息", i + 1);
		gotoxy(26, 22);
		color(14);
		printf("本程序会自动读取 请选择[ ]\b\b");
		char ch;
	label:
		ch = _getch();
		if (ch == 80)                 //下键的ASCII编码,当按下键时什么也不做等待for循环继续
		{

		}
		else if (ch == 27)
			Main_interface();        //Esc的ASCII编码
		else if (ch == 72)           //上键的ASCII编码
		{
			i -= 2;
		}
		else
			goto label;
	}
	char ch;
	gotoxy(24, 22);
	color(10);
	printf("请按Esc返回本程序会自动读取 [ ]\b\b");                          //结束返回                          
label3:
	ch = _getch();
	if (ch == 27)
		Main_interface();
	else
		goto label3;
}

/**********************删除信息**********************/
void Delete()
{
	system("cls");
	FILE* fp;
	XIN temp;
	XIN* h, * p, * q;      //*h代表链表的头指针,*p代表链表上一个的指针.*q代表当前指针
	int Const = 0;
	char Name[30];
	gotoxy(15, 2);
	color(11);
	printf("=========== 删 除 学 生 信 息 界 面===========\n");
	Bframe();
	color(14);
	gotoxy(20, 8);
	printf("请输入需要删除的学生名字:");
	scanf("%s", Name);
	if ((fp = fopen("studentA.datd", "rb")) == NULL)
	{
		printf("打开文件失败,请确定是否创建了该文件! 错误代码:0x006");
		exit(1);
	}
	h = p = (XIN*)malloc(sizeof(XIN));
	fread(&temp, sizeof(XIN), 1, fp);
	while (!feof(fp))                     //feof用检测流上的文件结束符,其返回值有两种情况:如果遇到文件结束,函数值为非零值,否则函数值为0
	{
		if (strcmp(temp.name, Name) == 0)
		{
			Const = 1;
			fread(&temp, sizeof(XIN), 1, fp);
			continue;
		}
		else
		{
			q = (XIN*)malloc(sizeof(XIN));             //把读取出来的内容赋值给q指向的结构体
			strcpy(q->Student_id, temp.Student_id);
			strcpy(q->name, temp.name);
			strcpy(q->sex, temp.sex);
			q->age = temp.age;
			q->Ascore = temp.Ascore;
			q->Bscore = temp.Bscore;
			q->Cscore = temp.Cscore;
			q->Count = temp.Count;
			p->next = q;
			p = q;                                    
			fread(&temp, sizeof(XIN), 1, fp);
		}
	}
	p->next = NULL;                                    

	if ((fp = fopen("studentA.datd", "rb")) == NULL)
	{
		printf("打开文件失败,请确定是否创建了该文件! 错误代码:0x006");
		exit(1);
	}

	p = h->next;                             //使p指向链表的第一个节点
	while (p->next != NULL)
	{
		fwrite(p, sizeof(XIN), 1, fp);
		p = p->next;
	}
	fclose(fp);
	if (Const == 1)
	{
		system("cls");
		gotoxy(15, 2);
		color(13);
		printf("=========== 删 除 学 生 信 息 界 面===========\n");
		Bframe();
		color(10);
		gotoxy(31, 8);
		printf("删 除 成 功 !");
		gotoxy(27, 14);
		color(13);
		printf("按Esc键返回主页面[ ]\b\b");
		char ch;
	labelA:
		ch = _getch();
		if (ch == 27)
			Main_interface();
		else
			goto labelA;
	}
	else
	{
		system("cls");
		gotoxy(15, 2);
		color(13);
		printf("=========== 删 除 学 生 信 息 界 面===========\n");
		Bframe();
		color(12);
		gotoxy(25, 8);
		printf("没有找到该学生的信息!");
		gotoxy(27, 14);
		color(13);
		printf("按Esc键返回主页面[ ]\b\b");
		char ch;
	labelB:
		ch = _getch();
		if (ch == 27)
			Main_interface();
		else
			goto labelB;
	}
}
void Aframe()                                    //彩色框架 1号  蓝 紫  中偏大 
{
	int i, j;
	static int b, n;
	for (i = 8; i <= 69; i++)
	{
		b = 2, n = 2;
		for (j = 4; j <= 20; j++)
		{
			b++;
			n++;
			if (i == 8 || i == 69)
			{
				if (b % 2 == 0)
				{
					color(13);
				}
				else if (b % 1 == 0)
				{
					color(9);
				}
				gotoxy(i, j);
				printf("|");
			}
			if (j == 4 || j == 20)
			{

				if (b % 2 == 0)
				{
					color(13);
				}
				else if (b % 1 == 0)
				{
					color(9);
				}
				gotoxy(i, j);
				printf("=");
			}

		}
	}
}
void Bframe()                          //彩色边框 2 蓝 红 偏小 
{
	int i, j;
	static int b, n;
	for (i = 8; i <= 69; i++)
	{
		b = 2, n = 2;
		for (j = 4; j <= 12; j++)
		{
			b++;
			n++;
			if (i == 8 || i == 69)
			{
				if (b % 2 == 0)
				{
					color(12);
				}
				else if (b % 1 == 0)
				{
					color(9);
				}
				gotoxy(i, j);
				printf("|");
			}
			if (j == 4 || j == 12)
			{

				if (b % 2 == 0)
				{
					color(12);
				}
				else if (b % 1 == 0)
				{
					color(9);
				}
				gotoxy(i, j);
				printf("=");
			}

		}
	}
}
int color(int n)             //颜色 ----------------------- 
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
	return 0;
}
void gotoxy(int x, int y)    //位置 --------------------------
{
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}


}


运行结果如图:
C语言实现学生管理系统_第1张图片

你可能感兴趣的:(链表,c语言,编程语言)