C语言学生管理系统

前言

很多学校都选择C语言作为学生编程入门语言,许多老师都会布置C语言期末大作业,作业题目很多就是学生信息管理系统,以前都是练习小题目,几十行代码就能搞定,而完整的写完这个系统我用了差不多400行代码。完整写完这个系统,是对一个学期所学知识的进一步深入了解于学习,还能扩充一些课外知识。篇幅很长,收藏起来,慢慢看!

题目详情

一、学生信息管理程序 基本要求:
1.要求实现学生信息的 使用帮助、添加、查找、删除、修改、浏览、保存、刷新、退出等9个功能,每个功能模块均能实现从模块中退出,从而完成一个学生管理系统所需功能。

2.要使用结构体来实现对学生信息的存储。

3.学生信息需至少包括:学号,姓名,性别,年龄, 成绩信息至少包括三科以上成绩:C语言、高数、英语…

4.使用文件完成数据的存储与读取,要求每次运行某个功能模块时将数据读入结构体中,并给用户提供保存选项,可以将结构体中的数据保存在文件中。

5.系统制作完成后应实现类似下图所示界面:
在这里插入图片描述

入坑全过程

整体思路

可以利用一个switch函数,加上代码模块化的思想,一个函数实现一个功能,分别实现题目要求的9个功能,为了让代码更加的模块化,额外增加一个菜单函数用于输出菜单界面,一共10个函数。

每个模块的具体实现方法

结构体的创建

题目要求需要使用结构体来对学生信息进行储存,所以需要创建一个结构体,同时也要注意结构体中需要包含学生的那些信息。
代码展示:

struct student
{
	char StuID[LEN];//学生学号 
	char Stuname[LEN];
	int Stuage;
	char Stusex;
	float score[3]; //三科成绩 
}stu[N];//N是学生人数,具体可以在代码开头进行更改
main函数
  1. 返回菜单界面以及exit(退出)函数的实现:
    由于每次执行完函数后,都要返回主菜单界面,所以用到一个while函数来控制循环,我们知道,当while的循环条件为 1(真)时,循环继续,否则(为0,就是假时)结束循环,利用这个特性,只需要用一个全局变量(我用的是 t)来控制循环即可,在定义时赋值为真(1),当执行exit函数(退出函数)时,将其值改为假(0)即可结束循环,实现退出。此思路后续exit函数的描述部分将不再说明。
  2. 除此之,就是switch函数实现菜单函数的选择执行,详细请看代码:
int main()
{
	int num;//num是菜单选项 
	while(t)//t是全局变量,用tuichu函数改变t的值来控制循环是否继续 
	{
		menu();//输出主菜单界面 
		printf("您好,请输入菜单编号:");
		scanf("%d",&num); 
		switch(num)
		{
			case 1: help(); break;
			case 2: increase(); break;
			case 3: seek(); break;
			case 4: de(); break;
			case 5: save(); break;
			case 6: present(); break;
			case 7: modify(); break;
			case 8: flush(); break; 
			case 9: tuichu(); break;
			default:printf("输入有误,请重新输入!");	
	}
	} 
	
menu函数

menu函数就只有一个功能,输出菜单界面,界面的美化与格式的控制相信都比我强,哈哈,废话不多说,上代码:

void menu()
{
	printf("\n\n");
	printf("*****************************************************\n");
	printf("*----------------------duoduo------------------------\n");	
	printf("*                 学生信息管理系统                  *\n");
	printf("*****************************************************\n");
	printf("********************系统功能菜单*********************\n");
	printf("----------------------     --------------------------\n");
	printf("*****************************************************\n");
	printf("**    1、使用帮助       *     2、增加学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    3、查询学生信息   *     4、删除学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    5、保存当前信息   *     6、显示当前信息      **\n");
	printf("*****************************************************\n");
	printf("**    7、修改学生信息   *     8、刷新学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    9、退出系统       *                          **\n");
	printf("*************************                            \n");
	printf("----------------------     --------------------------\n");
	
} 
help函数

help函数是给用户的提示,也不做多的解释,直接上代码:

void help() 
{
	printf("\n这是一个学生信息管理系统,为了帮助您更快的了解使用它,请先仔细阅读以下注意事项:\n");
	printf("\n                  注意事项:                    \n ");
	printf("\n       1、请根据提示进行操作!\n");
	printf("\n       2、初次使用请先选择增加学生信息!\n");
	printf("\n       3、修改或者增加学生信息后切记保存!\n");
	printf("\n       4、如果数据有错误,请先修改再保存!\n"); 
	printf("\n       5、若您之前使用过,下次进入系统请先刷新学生信息!\n");
	printf("\n       6、在添加学生时,用两个字符代表不同的性别,比如男用‘M’代替,女用‘W’代替!\n");
	printf("\n       7、保存或者刷新时,输入的文件名后缀请使用.txt,比如: stu.txt,系统会在源程序\n");
	printf("\n          “学生管理系统.exe”的相同目录建立一个.txt文件来保存学生信息,您可以查看\n"); 
	printf("\n          该文件,但非专业人员不要轻易改动,否则会造成刷新数据异常或刷新失败!\n");	
	printf("\n       8、学生信息包括:姓名、学号、性别、年龄、C语言成绩、高数成绩、英语成绩等!\n");
	printf("\n       9、使用遇到任何问题请与我们联系,邮箱:ouyang_na_na@163.com\n");
	printf("\n       10、最后感谢您的使用!\n"); 
	system("pause"); 
} 

这里解释一下system("pause");因为课堂上以及平时做题我们都很少用它,实际上它的作用就是让系统暂停,方便我们阅读或者是观察程序,在执行程序时就是下面这样的:
在这里插入图片描述
很熟悉吧,没错,就是请按任意键继续,让系统暂停。下面还会
多次用到,将不再解释了哟。

increase函数

increase函数算是该系统的核心函数之一,其函数思想用到了循环的嵌套使用,还有flag的运用也与前面main函数中用 t 控制循环有异曲同工之处。主要分为两大步骤来完成:

  1. 判断新加入的学生学号是否已经存在,这一步用到了一个flag来作为标志,如果存在就要重新输入,让flag=1,即可让循环继续,不存在flag=0,结束循环,进入下一步。
  2. 添加学生信息,这一步就是简单的输入赋值,需要注意的是利用getchar()函数来处理换行符这个小技巧。

其余的细节代码中我已经详细的解释,可以看看代码,
代码:

void increase()
{
	int i=n,j,flag,m=0;//i代表增加学生信息过程中任意时刻的学生人数 
	printf("\n请输入待增加的学生人数:\n");
	scanf("%d",&m);
	if(m>0){
	do{
		flag=1;
		while(flag)
		{
			flag=0;
			printf("请输入第%d位学生的学号:\n",i+1);//第几位学生从1开始计数,而stu[]从零开始,需要加1 
			scanf("%s",stu[i].StuID);
			//判断学号是否重复
			for(j=0;j<i;j++){
				if(strcmp(stu[i].StuID,stu[j].StuID)==0){
					printf("该学号已经存在,请重新输入!\n");	
					flag=1;
					break;			
				}	 
			}
		}
		printf("请输入第%d位学生姓名:\n",i+1);
		scanf("%s",stu[i].Stuname); 
		printf("请输入第%d位学生年龄:\n",i+1);
		scanf("%d",&stu[i].Stuage); 
		getchar();//处理上面输入的换行符,不然系统会把换行符当做一个字符赋值给性别 
		printf("请输入第%d位学生性别:\n",i+1);	
		scanf("%c",&stu[i].Stusex);
		printf("请输入第%d位学生的C语言成绩:\n",i+1);
		scanf("%f",&stu[i].score[0]);
		printf("请输入第%d位学生的高数成绩:\n",i+1);
		scanf("%f",&stu[i].score[1]);
		printf("请输入第%d位学生的大学英语成绩:\n",i+1);
		scanf("%f",&stu[i].score[2]);
		i++;
		}while(i<n+m);//只要当前学生人数还没到达添加后的总人数,就得继续添加		
	}
	n+=m;// 添加完成,系统人数n的值也要增加 
	printf("添加完成!!!\n");
	system("pause");
} 
seek 函数

seek查找函数,调用此函数,可以实现按姓名或者学号查找某一学生的信息。其核心思路也是用到了switch函数输入子菜单的方式来实现的,同时又用flag作为标志来判断是否已经查找到该学生信息。考虑到需要查找学生信息的次数不止一次,就需要用到while函数来实现循环,可以看到循环条件是1(永远为真),有人可能会说:那这不就是死循环吗?实际上除了让循环条件为假,还可以用其它方式结束循环,比如用return语句,代码后面介绍。
代码:

void seek()
{
	int i,num,flag;
	char s1[LEN+1];
	printf("*****************************\n");
	printf("**-------1.按学号查询------**\n");
	printf("**-------2.按姓名查询------**\n");
	printf("**-------3.退出本菜单------**\n");
	printf("*****************************\n");
	while(1)
	{
		flag=0;
		printf("请输入子菜单:");
		scanf("%d",&num);
		switch(num)
		{
			case 1:
			printf("请输入需要查找学生的学号:\n");
			scanf("%s",s1);
			for(i=0;i<n;i++)
			{
				if(strcmp(stu[i].StuID,s1)==0)
				{
					flag=1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n",stu[i].StuID,stu[i].Stuname,stu[i].Stusex,stu[i].Stuage,stu[i].score[0],stu[i].score[1],stu[i].score[2]);
				}	
			}break;	
			case 2:
			printf("请输入需要查找学生的姓名:\n");
			scanf("%s",s1);
			for(i=0;i<n;i++)
			{
				if(strcmp(stu[i].Stuname,s1)==0)
				{
					flag=1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n",stu[i].StuID,stu[i].Stuname,stu[i].Stusex,stu[i].Stuage,stu[i].score[0],stu[i].score[1],stu[i].score[2]);
				}	
			}break;		
			case 3: return;
			default: printf("请在1--3之间输入\n");
		}
		if(flag==0)
		printf("找不到该学生!\n请重新输入!"); 
	} 
} 

这里解释一下子菜单三:
可以看到,后面我直接用了一个return语句来实现退出,是因为return函数具有把程序流程从被调用函数转向主函数的作用,一旦遇到return就会立即结束正在执行的函数,平时用的return语句后面都是跟参数返回值的,实际上也可以不跟参数,仅仅代表结束此函数。
后面的修改学生信息的modify函数也用到这种思想,将不再解释,嘿嘿。

de函数

de函数是删除学生信息的函数,调用此函数,可以按照学号删除学生信息,核心思想:

  1. 找到该学生的位置
  2. 接着把该名学生后面的学生往前移动一位,学生总人数再减去一
  3. flag的应用,用于判断是否已经找到该学号的学生,方便结束循环,以及给用户的提示。

代码:

void de()
{
	int i,j,flag;
	char s1[LEN];
	printf("请输入需要删除的学生学号:\n");
	scanf("%s",s1);
	flag=0;
	for(i=0;i<n;i++)
	{
		if(strcmp(s1,stu[i].StuID)==0)
		{
			flag=1;
			for(j=i;j<n-1;j++)
			{
				stu[j]=stu[j+1];//直接把后面的学生都往前移动一位 
			}
		}
		if(flag==1) break;//说明已经找到了需要删除的学生,结束循环 
	} 
	 if(0==flag)
	 {
	 	printf("该学号不存在!!!\n");
	 }
	
	if(1==flag)
	{	
		printf("删除成功\n");
		n--;		
	}
	system("pause");
}
save函数

save有保存的意思,哈哈,平时用的ctrl+s应该就是它,我也是写了这个才知道的,如果你和我一样,那就记住了哦!扯远了,进入正题。
一旦调用save函数,就只有一个作用,就是把程序中结构体中现有的信息输出到文件保存起来,该部分算是我写这个程序的难点之一,因为关于文件的知识需要自己看书查资料,先看代码再解释其中的难点。
代码:

void save()//把学生信息保存到文件 
{
	int i;
	FILE *fp;
	char filename[LEN+1];
	printf("请输入要保存的文件名:\n"); 	
	scanf("%s",filename);
	if((fp=fopen(filename,"w"))==NULL)
	{
		printf("打开文件失败!\n");
		exit(0);	
	}
	for(i=0;i<n;i++)
	if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
	printf("保存失败!!\n");
	printf("保存成功!!!\n");
	fclose(fp);
	system("pause");
}

这里需要解释的主要有两个部分:
第一部分:

if((fp=fopen(filename,"w"))==NULL)
	{
		printf("打开文件失败!\n");
		exit(0);	
	}
  • fopen是打开文件的函数,它的形式参数中的filename是需要我们提前输入的一个字符型数组,代表文件名,"w"是指以只写(只写就是只向文件输出信息,不读取)的方式打开文件。
  • fopen函数首先会在.exe源程序的相同目录查找之前输入的文件名,如果不存在该文件名,就会新建一个;如果存在,就会删除原文件,重新建立一个新的文件。
  • fopen函数的返回值是指向该文件的指针的指针,此处用使fp指向它的返回值。

第二部分:

for(i=0;i<n;i++)
	if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
	printf("保存失败!!\n");
	printf("保存成功!!!\n");

for循环不多作解释,重点说一下fwrite函数与后面flush函数中需要用到的fread函数,后面flush函数用到将不在解释。
其一般调用形式为:
fwrite(buffer,size,count,fp);buffer中的数据每次输出"size x count "字节长度的数据到fp所指的文件中。
fread(buffer,size,count,fp);fp所指的文件中每次读入"size x count "字节长度的数据到buffer对应的地址中。

下面依次解释每个参数:

  • buffer:是一个地址,是用来存放从文件读入的数据(对fread函数来说)或者输出到文件的数据的来源(对fwrite函数来说)。
  • size:要读写的字节数
  • count:要读写多少个数据项(每个数据项长度为size)。
  • fp:FILE类型的指针。

对于两个函数来说,只要其成功执行,就会返回count的值,程序中为1。

present函数

一旦调用present函数,就显示当前所有的学生信息,用简单的for循环输出即可,需要注意结构体中的数据类型不要弄错了,同时注意控制格式,"\t" 就是tab健的那个空格,这里用两个 “\t” 是为了解决学生姓名或者学号太长而引起的上下格式不对应的问题.

代码:

void present()
{
	int i;
	
	if(n==0)
	{
		printf("您好,现在没有学生信息,请先增加学生信息或者刷新再来试试!\n");
	}
	else
	{
		printf("现在共有%d名学生:\n",n);
		printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
		for(i=0;i<n;i++)
		{
			printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n",stu[i].StuID,stu[i].Stuname,stu[i].Stusex,stu[i].Stuage,stu[i].score[0],stu[i].score[1],stu[i].score[2]);	
		}
	}
		
	system("pause");	
}

如果只用一个 “\t” ,当名字或者学号过长时,就会出现下面这种情况:
在这里插入图片描述
可以发现,由于姓名太长,性别的位置已经被姓名占据了,后面就会出现错位的情况。

modify函数

调用该函数即可修改任意学生的任意信息,考虑到可能需要修改学生的多向信息,所以用到while函数,且循环条件永远为真,相同的思路前面seek函数中已经说过,不再解释。也同样用到flag作为是否找到学生的标志,方便于没有找到的情况下重新输入姓名,以及对用户的提示。核心思路还是switch语句,子菜单实现修改,具体请看代码:

void modify()
{
	int i,flag;
	char ID[LEN],name[LEN],sex;
	int age;
	float score;//以上命名顾名思义,不作解释
	printf("请输入需要修改的学生姓名:\n");
	getchar();
	gets(name);
	
	while(1)
	{	
		flag=0;
		for(i=0;i<n;i++)
		{
			if(strcmp(name,stu[i].Stuname)==0)
			{
				flag=1;
				int num;//用于switch函数的子菜单 
				printf("***************************************************\n");
				printf("*----1.修改学号--------  -  -----2.修改性别-------*\n");
				printf("*----3.修改年龄--------  -  -----4.修改C语言成绩--*\n");
				printf("*----5.修改高数成绩----  -  -----6.修改英语成绩---*\n");
				printf("*-------------------7.退出本菜单------------------*\n");
				printf("***************************************************\n\n");
				printf("请输入子菜单:");
				scanf("%d",&num);
				switch(num)
				{
					case 1:	
					printf("请输入新的学号:\n");
					getchar();
					gets(ID);
					strcpy(stu[i].StuID,ID);break;
					case 2:
					getchar();	
					printf("请输入新的性别:\n");
					scanf("%c",&sex);
					stu[i].Stusex=sex;break;
					case 3:
					printf("请输入新的年龄:\n");
					scanf("%d",&age);
					stu[i].Stuage=age;break;
					case 4:
					printf("请输入新的C语言成绩:\n");
					scanf("%f",&score);
					stu[i].score[0]=score;break;
					case 5:
					printf("请输入新的高数成绩:\n");
					scanf("%f",&score);
					stu[i].score[1]=score;break;
					case 6:
					printf("请输入新的英语成绩:\n");
					scanf("%f",&score);
					stu[i].score[2]=score;break;
					case 7:
					return;break; 
					default:
					printf("请在1--7之间选择!\n");
				}
				if(num>0&&num<7)
				printf("修改成功,记得保存哟!!!\n");
				break;//找到学生,结束循环;	
			}
		}	
		if(flag==0)
		{
			printf("没有找到该学生,请重新输入需要修改信息的学生姓名:\n");
			gets(name);
		}
	}
	system("pause");	
}
flush函数

调用flush函数,即可将之前文件中的数据读入结构体中来进行操作。需要注意的两个地方,一个是fread() 函数的使用,前面save函数已经介绍过,不再解释;还有就是

	if((fp=fopen(filename,"r"))==NULL)//打开文件 

中的 “r” 代表以只读(只从文件读取数据)的方式打开文件。
代码:

void flush()
{
	int i,k=0;//k代表刷新过程中学生人数 
	FILE *fp;
	char filename[LEN+1];
	printf("请输入需要刷新的文件名:\n");
	getchar(); 
	gets(filename);
	if((fp=fopen(filename,"r"))==NULL)//打开文件 
	{
		printf("打开文件失败!\n");
		exit(0);
	}
	for(i=0;i<N;i++)//N是最大的学生人数,可在程序开头进行更改 
	{
		if(fread(&stu[i],sizeof(struct student),1,fp)==1)
		k++;//记录学生人数 
	}	
	n=k;// 把k的值给n 
	if(k==0)
	printf("刷新失败!!!\n");
	else
	printf("刷新成功!!!\n"); 
	fclose(fp);
	system("pause");
	
}
tuichu函数

main函数中已经简单介绍过,就是通过改变main函数中的循环条件 “t” 的值来实现程序的结束与否。
代码:

void tuichu()
{
	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");	
	}
		
}

整个程序代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>//需要用到strcmp函数 

#define LEN 15//姓名和学号的最大字符数 
#define N 50//最大学生人数

int n = 0, t = 1;//n代表当前学生人数,t用来控制整个程序的执行,以及程序的退出; 

//函数声明
void menu();//主菜单函数 
void help();//使用帮助 
void increase();//增加学生信息  
void seek();//查找学生信息
void de();//删除学生信息 
void save();//保存文件
void present();//显示当前信息
void modify();//修改学生信息   
void flush();//刷新学生成绩 
void tuichu();//退出函数 

struct student
{
	char StuID[LEN];//学生学号 
	char Stuname[LEN];
	int Stuage;
	char Stusex;
	float score[3]; //各科成绩 
}stu[N];

int main()
{
	int num;//num是菜单选项 
	while (t)//t是全局变量,用tuichu函数来控制循环是否继续 
	{
		menu();//输出主菜单界面 
		printf("您好,请输入菜单编号:");
		scanf("%d", &num);
		switch (num)
		{
		case 1: help(); break;
		case 2: increase(); break;
		case 3: seek(); break;
		case 4: de(); break;
		case 5: save(); break;
		case 6: present(); break;
		case 7: modify(); break;
		case 8: flush(); break;
		case 9: tuichu(); break;
		default:printf("输入有误,请重新输入!");
		}


	}

	system("pause");
	return 0;
}
void menu()
{
	printf("\n\n");
	printf("*****************************************************\n");
	printf("*----------------------duoduo------------------------\n");
	printf("*                 学生信息管理系统                  *\n");
	printf("*****************************************************\n");
	printf("********************系统功能菜单*********************\n");
	printf("----------------------     --------------------------\n");
	printf("*****************************************************\n");
	printf("**    1、使用帮助       *     2、增加学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    3、查询学生信息   *     4、删除学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    5、保存当前信息   *     6、显示当前信息      **\n");
	printf("*****************************************************\n");
	printf("**    7、修改学生信息   *     8、刷新学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    9、退出系统       *                          **\n");
	printf("*************************                            \n");
	printf("----------------------     --------------------------\n");

}
void help()
{
	printf("\n这是一个学生信息管理系统,为了帮助您更快的了解使用它,请先仔细阅读以下注意事项:\n");
	printf("\n                  注意事项:                    \n ");
	printf("\n       1、请根据提示进行操作!\n");
	printf("\n       2、初次使用请先选择增加学生信息!\n");
	printf("\n       3、修改或者增加学生信息后切记保存!\n");
	printf("\n       4、如果数据有错误,请先修改再保存!\n");
	printf("\n       5、若您之前使用过,下次进入系统请先刷新学生信息!\n");
	printf("\n       6、在添加学生时,用两个字符代表不同的性别,比如男用‘M’代替,女用‘W’代替!\n");
	printf("\n       7、保存或者刷新时,输入的文件名后缀请使用.txt,比如: stu.txt,系统会在源程序\n");
	printf("\n          “学生管理系统.exe”的相同目录建立一个.txt文件来保存学生信息,您可以查看\n");
	printf("\n          该文件,但非专业人员不要轻易改动,否则会造成刷新数据异常或刷新失败!\n");
	printf("\n       8、学生信息包括:姓名、学号、性别、年龄、C语言成绩、高数成绩、英语成绩等!\n");
	printf("\n       9、使用遇到任何问题请与我们联系,邮箱:ouyang_na_na@163.com\n");
	printf("\n       10、最后感谢您的使用!\n");
	system("pause");
}

void increase()
{
	int i = n, j, flag, m = 0;//i代表增加学生信息过程中任意时刻的学生人数 
	printf("\n请输入待增加的学生人数:\n");
	scanf("%d", &m);
	if (m > 0) {
		do {
			flag = 1;
			while (flag)
			{
				flag = 0;
				printf("请输入第%d位学生的学号:\n", i + 1);//第几位学生从1开始计数,而stu[]从零开始,需要加1 
				scanf("%s", stu[i].StuID);
				//判断学号是否重复
				for (j = 0; j < i; j++) {
					if (strcmp(stu[i].StuID, stu[j].StuID) == 0) {
						printf("该学号已经存在,请重新输入!\n");
						flag = 1;
						break;
					}
				}
			}
			printf("请输入第%d位学生姓名:\n", i + 1);
			scanf("%s", stu[i].Stuname);
			printf("请输入第%d位学生年龄:\n", i + 1);
			scanf("%d", &stu[i].Stuage);
			getchar();//处理上面输入的换行符,不然系统会把换行符当做一个字符赋值给性别 
			printf("请输入第%d位学生性别:\n", i + 1);
			scanf("%c", &stu[i].Stusex);
			printf("请输入第%d位学生的C语言成绩:\n", i + 1);
			scanf("%f", &stu[i].score[0]);
			printf("请输入第%d位学生的高数成绩:\n", i + 1);
			scanf("%f", &stu[i].score[1]);
			printf("请输入第%d位学生的大学英语成绩:\n", i + 1);
			scanf("%f", &stu[i].score[2]);
			i++;
		} while (i < n + m);//只要当前学生人数还没到达添加后的总人数,就得继续添加		
	}
	n += m;// 添加完成,系统人数n的值也要增加 
	printf("添加完成!!!\n");
	system("pause");
}
void seek()
{
	int i, num, flag;
	char s1[LEN + 1];
	printf("*****************************\n");
	printf("**-------1.按学号查询------**\n");
	printf("**-------2.按姓名查询------**\n");
	printf("**-------3.退出本菜单------**\n");
	printf("*****************************\n");
	while (1)
	{
		flag = 0;
		printf("请输入子菜单:");
		scanf("%d", &num);
		switch (num)
		{
		case 1:
			printf("请输入需要查找学生的学号:\n");
			scanf("%s", s1);
			for (i = 0; i < n; i++)
			{
				if (strcmp(stu[i].StuID, s1) == 0)
				{
					flag = 1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
				}
			}break;
		case 2:
			printf("请输入需要查找学生的姓名:\n");
			scanf("%s", s1);
			for (i = 0; i < n; i++)
			{
				if (strcmp(stu[i].Stuname, s1) == 0)
				{
					flag = 1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
				}
			}break;
		case 3: return;
		default: printf("请在1--3之间输入\n");
		}
		if (flag == 0)
			printf("找不到该学生!\n请重新输入!");
	}
}
void de()
{
	int i, j, flag;
	char s1[LEN];
	printf("请输入需要删除的学生学号:\n");
	scanf("%s", s1);
	flag = 0;
	for (i = 0; i < n; i++)
	{
		if (strcmp(s1, stu[i].StuID) == 0)
		{
			flag = 1;
			for (j = i; j < n - 1; j++)
			{
				stu[j] = stu[j + 1];//直接把后面的学生都往前移动一位 
			}
		}
		if (flag == 1) break;//说明已经找到了需要删除的学生,结束循环 
	}
	if (0 == flag)
	{
		printf("该学号不存在!!!\n");
	}

	if (1 == flag)
	{
		printf("删除成功\n");
		n--;
	}
	system("pause");
}

void save()//把学生信息保存到文件 
{
	int i;
	FILE* fp;
	char filename[LEN + 1];
	printf("请输入要保存的文件名:\n");
	scanf("%s", filename);
	if ((fp = fopen(filename, "w")) == NULL)
	{
		printf("打开文件失败!\n");
		exit(0);
	}
	for (i = 0; i < n; i++)
		if (fwrite(&stu[i], sizeof(struct student), 1, fp) != 1)
			printf("保存失败!!\n");
	printf("保存成功!!!\n");
	fclose(fp);
	system("pause");
}

void present()
{
	int i;

	if (n == 0)
	{
		printf("您好,现在没有学生信息,请先增加学生信息或者刷新再来试试!\n");
	}
	else
	{
		printf("现在共有%d名学生:\n", n);
		printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
		for (i = 0; i < n; i++)
		{
			printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
		}
	}

	system("pause");
}

void modify()
{
	int i, flag;
	char ID[LEN], name[LEN], sex;
	int age;
	float score;
	printf("请输入需要修改的学生姓名:\n");
	getchar();
	gets(name);

	while (1)
	{
		flag = 0;
		for (i = 0; i < n; i++)
		{
			if (strcmp(name, stu[i].Stuname) == 0)
			{
				flag = 1;
				int num;//用于switch函数的子菜单 
				printf("***************************************************\n");
				printf("*----1.修改学号--------  -  -----2.修改性别-------*\n");
				printf("*----3.修改年龄--------  -  -----4.修改C语言成绩--*\n");
				printf("*----5.修改高数成绩----  -  -----6.修改英语成绩---*\n");
				printf("*-------------------7.退出本菜单------------------*\n");
				printf("***************************************************\n\n");
				printf("请输入子菜单:");
				scanf("%d", &num);
				switch (num)
				{
				case 1:
					printf("请输入新的学号:\n");
					getchar();
					gets(ID);
					strcpy(stu[i].StuID, ID); break;
				case 2:
					getchar();
					printf("请输入新的性别:\n");
					scanf("%c", &sex);
					stu[i].Stusex = sex; break;
				case 3:
					printf("请输入新的年龄:\n");
					scanf("%d", &age);
					stu[i].Stuage = age; break;
				case 4:
					printf("请输入新的C语言成绩:\n");
					scanf("%f", &score);
					stu[i].score[0] = score; break;
				case 5:
					printf("请输入新的高数成绩:\n");
					scanf("%f", &score);
					stu[i].score[1] = score; break;
				case 6:
					printf("请输入新的英语成绩:\n");
					scanf("%f", &score);
					stu[i].score[2] = score; break;
				case 7:
					return; break;
				default:
					printf("请在1--7之间选择!\n");
				}
				if (num > 0 && num < 7)
					printf("修改成功,记得保存哟!!!\n");
				break;//找到学生,结束循环;	
			}
		}
		if (flag == 0)
		{
			printf("没有找到该学生,请重新输入需要修改信息的学生姓名:\n");
			gets(name);
		}
	}
	system("pause");
}

void flush()
{
	int i, k = 0;//k代表刷新过程中学生人数 
	FILE* fp;
	char filename[LEN + 1];
	printf("请输入需要刷新的文件名:\n");
	getchar();
	gets(filename);
	if ((fp = fopen(filename, "r")) == NULL)//打开文件 
	{
		printf("打开文件失败!\n");
		exit(0);
	}
	for (i = 0; i < N; i++)//N是最大的学生人数,可在程序开头进行更改 
	{
		if (fread(&stu[i], sizeof(struct student), 1, fp) == 1)
			k++;//记录学生人数 
	}
	n = k;// 把k的值给n 
	if (k == 0)
		printf("刷新失败!!!\n");
	else
		printf("刷新成功!!!\n");
	fclose(fp);
	system("pause");

}
void tuichu()
{
	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");
	}

}	
	



	

运行结果展示

  • menu函数
    在这里插入图片描述

  • help函数
    在这里插入图片描述

  • increase函数
    在这里插入图片描述

  • seek函数
    在这里插入图片描述

  • de函数
    在这里插入图片描述

  • save函数
    在这里插入图片描述

  • present函数
    在这里插入图片描述

  • modify函数
    在这里插入图片描述

  • flush函数
    在这里插入图片描述

  • exit函数
    在这里插入图片描述

写在最后

完整的写完这个系统我用了差不多400行代码。完整写完这个系统,全文接近两万字,话了很久的时间,创作不易(好一点的文章都是付费的)如果你觉得对你有一点点帮助,那就点赞,收藏,留言,有问题还可以私信我,看到了尽量回复!

Logo

助力合肥开发者学习交流的技术社区,不定期举办线上线下活动,欢迎大家的加入

更多推荐