学生信息管理系统(C语言)

高级程序设计:学生管理系统(C语言)

本项目可以简单的实现学生信息的增、删、改、查、统计、存储等基本功能:(环境是Dev C++)

  1. 创建学生信息文件,根据提示输入学生的各项信息,然后按学号对学生信息进行排序,并将排序后的学生信息存储到文件中。
  2. 增加学生信息,在原有学生信息文件的基础上增加新的学生成绩信息。要求:增加后的学生信息仍按学号排序,并继续保存至原文件。
  3. 删除学生信息,提示用户输入要进行删除操作的学号,如果在文件中有该信息存在,则将该学号所对应的学生信息删除,否则输出提示信息,并提示用户选择是否继续进行删除操作。
  4. 修改学生信息,提示用户输入要进行修改操作的学号,如果在文件中有该息存在,则将提示用户输入该学号对应的要修改的选项,结果保存至原文件,并提示用户选择是否继续进行修改操作。
  5. 查询学生信息,按不同条件对学生信息进行查询操作,输出满足条件的学生信息。
  6. 基本统计信息,可对学生信息进行基本的统计分析。

功能模块

输入模块
增加信息模块
删除信息模块
修改信息模块
查询统计信息模块

项目源码

/********************************************************************************
* @File name: main.c
* @Description: 该程序主要实现的是学生信息管理,保存了学生的基本信息,包括学号、姓名、班级、
                语文成绩、数学成绩、英语成绩、物理成绩以及总成绩这些数据,具体可实现的操作有
				1.	创建学生信息文件,根据提示输入学生的各项信息,然后按学号对学生信息进行排序,
				并将排序后的学生信息存储到文件中。
                2.	增加学生信息,在原有学生信息文件的基础上增加新的学生成绩信息。
				并且增加后的学生信息仍按学号排序,并继续保存至原文件。
                3.	删除学生信息,提示用户输入要进行删除操作的学号,如果在文件中有该信息存在,
				则将该学号所对应的学生信息删除,否则输出提示信息,并提示用户选择是否继续进行删除操作。
                4.	修改学生信息,提示用户输入要进行修改操作的学号,如果在文件中有该息存在,
				则将提示用户输入该学号对应的要修改的选项,结果保存至原文件,并提示用户选择是否继续进行修改操作。
                5.	查询学生信息,按不同条件对学生信息进行查询操作,输出满足条件的学生信息。
                6.	基本统计信息,可对学生信息进行基本的统计分析。
 
* @ Function List: 
				void show();//显示信息 
				void input();//输入信息 
				void search();//查询信息
				void del();//删除信息
				void modify();//修改信息
				void order();//排序
				void number();//学生人数的统计 
				void surface();//管理系统的界面显示 

* @Author: 千阴 
* @Date: 2019-12-22
* @History: 无 
********************************************************************************/

#include<stdio.h> 
#include<stdlib.h>
#include<string.h>//C语言里面关于字符数组的函数定义的头文件,常用函数有strlen、strcmp、strcpy等等
#include<conio.h>//用getchar()、getch()就要包含<conio.h>的头文件 
#include<dos.h> 

#define LEN  sizeof(struct student)//学生结构体数组的长度 
#define FORM "%d%10s%16s%13d%15d%15d%15d%19.2f\n"//为了使得每次的输出信息时更加简单方便,把这个设为一个常量 
#define DATE  stu[i].num,stu[i].name,stu[i].clas,stu[i].chiness_score,stu[i].math_score,stu[i].english_score,stu[i].wuli_score,stu[i].sum//输出数据的信息

/*定义一个学生类型的结构体,用于存放学生的信息*/ 
struct student 
{
	int num;/*学号 */ 
	char name[20];/*姓名 */
	char clas[20];/*班级 */
	int chiness_score;/*语文成绩 */       
	int math_score;/*数学成绩 */
	int english_score;/*英语成绩*/
	int wuli_score; /*物理成绩*/ 
	float sum;/*总成绩 */
}stu[100];//由于不知道输入多少名学生信息,所以先开始将数组的长度设计得长一些 

int main()
{
	  //对各函数模板进行声明
	void show();//显示信息 
	void input();//输入信息 
	void search();//查询信息
	void delet();//删除信息
	void revise();//修改信息
	void order();//排序
	void number();//统计学生人数 
	void surface();//界面 
	//void bben();//界面信息 
	int n;
	//bben();
	surface();
  scanf("%d",&n);//输入选择功能的编号
  while(n)
  { switch(n)
     { case 1: input();break;
       case 2: search();break;
       case 3: delet();break;
       case 4: revise();break;
       case 5: order();break;
       case 6: number();break;
       case 7: show();printf("请按任意键返回菜单!\n");break;
       default:break;
     }
    getch();
    surface();//执行完功能再次显示菜单界面
    scanf("%d",&n);//输入选择功能的编号
  }
  return 0;
}

void surface()
{
	system("cls");//利用系统的API函数进行清屏处理 
	printf(" -------------学生信息管理系统-------------\n");
	printf(" |                                         |\n");
	printf(" |   该系统中你可以实现的具体操作如下:    |\n");
	printf(" |             1.输入信息                  |\n");
	printf(" |             2.查询信息                  |\n");
	printf(" |             3.删除信息                  |\n");
	printf(" |             4.修改信息                  |\n");
	printf(" |             5.排序输出                  |\n");
	printf(" |             6.学生人数                  |\n");
	printf(" |             7.显示信息                  |\n");
	printf(" |             0.退出                      |\n");
	printf(" ------------------------------------------\n");
	printf(" 请输入您要执行的序号(0--7):               ");
	
}

void show()
 { FILE *fp;
   int i,a=0;//控制变量 
   fp=fopen("data.txt","rb");//打开文件 
   while(!feof(fp))//判断文件指针*fp是否指向文件的末尾 
   {
   if(fread(&stu[a] ,LEN,1,fp)==1) 
   a++;
   }  
   fclose(fp);//关闭文件 
   printf("学号     姓名     班级       语文        数学       英语    物理     成绩总分\t\n");
   for(i=0;i<a;i++)
       { 
	   printf(FORM,DATE);//将信息在界面上显示出来,FORM表示的是数据的格式,DATE表示需要显示的数据 
       }
}

void input()//添加录入学生信息的小模块 
{
	
	int i,a=0,n;//a变量是记录学生信息的条数,i和n都充当循环变量 
	char ch[2];//保存判断的字符,分别是 Y和 N 
	FILE *fp;//定义文件指针
	if((fp=fopen("data.txt","a+"))==NULL)//打开指定文件  a+:为读/写打开一个指定文件  
	                                    //第一次打开文件,寻找原本存在的学生信息并且显示出来 
	{
		printf("不能打开文件\n");
		return;
	} 
	while(!feof(fp))//feof是END Of File的缩写形式,用于测试流文件的结束 
	{
		if(fread(&stu[a],LEN,1,fp)==1)// 用于文件流中读取数据 
		a++;                             //记录当前条数 
	
	}
	fclose(fp);//关闭文件 
	if(a==0)
	printf("不能记录!\n");
	else
	{
		system("cls");//清屏操作,刷新结果 
		show();//显示主界面的信息和需要输出的结果 
    }
    if((fp=fopen("data.txt","wb"))==NULL)//wb表示只写,为输出打开一个二进制文件   
	                                    //第二次打开文件,往文件里写入学生信息 
    {
    	printf("不能打开文件\n");//如果打开文件为NULL,则会输出不能打开文件的信息 
    	return ;
    }
    for(i=0;i<a;i++)
    fwrite(&stu[i],LEN,1,fp);//LEN代表学生数组的长度 
    printf("请输入y/n(提示,输入y继续输入,输入n结束输入):");//为了防止错误删除信息,所以设置了提醒信息 
    scanf("%s",ch);
    while(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)
    {
    	printf("学号:");
		scanf("%d",&stu[a].num);//输入学号 
		for(i=0;i<a;i++)
		if(stu[i].num==stu[a].num)//判断信息是否已经存在了 ,如果已经存在,就不写入信息 
		{
			printf("该学号已存在,请按任何键继续!");
			getch();
			fclose(fp);
			return;
		}
		printf("姓名:");
		scanf("%s",stu[a].name);
		printf("班级:");
		scanf("%s",stu[a].clas);
		printf("语文:");
		scanf("%d",&stu[a].chiness_score);
		printf("数学:");
		scanf("%d",&stu[a].math_score);
		printf("英语:");
		scanf("%d",&stu[a].english_score);
		printf("物理:");
		scanf("%d",&stu[a].wuli_score);
		stu[a].sum=stu[a].chiness_score+stu[a].math_score+stu[a].english_score+stu[a].wuli_score;
		if(fwrite(&stu[a],LEN,1,fp)!=1)//将信息写入文件中 
		{
			printf("不能保存!");
			getch();
		}
		else
		{
			printf("%s 已被保存!\n",stu[a].name);
			a++;
		}
		printf("是否继续y/n(提示,输入y继续输入,输入n结束输入):");//判断是否继续向里面输入数据 
		scanf("%s",ch);
    }
    fclose(fp);
    printf("OK!请按任意键返回主菜单!\n");
}

void search()//查询学生信息 
{
FILE *fp;
int snum,i,a=0;//snum是一个用于记录学号的中间变量 
char ch[2];
if((fp=fopen("data.txt","rb"))==NULL)//rb是以二进制的方式对文件进行只读操作
{
 printf("不能打开文件\n");
 return;	
}
while(!feof(fp)) //测试流文件是否结束 
{
if(fread(&stu[a],LEN,1,fp)==1)//向文件里面读数据 
  a++;
  }
  
  fclose(fp);
if(a==0)
{
	printf("没有记录!\n");
	return;
}	
printf("请输入要查询学生的学号:");//以下操作是按照学号来查找学生的信息 
scanf("%d",&snum);
for(i=0;i<a;i++)
if(snum==stu[i].num)
{
	printf("已经找出该学生,是否要显示(y/n):");
	scanf("%s",ch);
	if(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)
	{
		printf("学号     姓名     班级       语文        数学       英语    物理     成绩总分\t\n");
		printf(FORM,DATE); 
		break;
	}
	}
if(i==a) printf("未能找到要查询的信息!\n");
printf("请按任意键返回主菜单!\n");
}

void delet()//删除学生信息 
{
FILE *fp;
int snum,i,j,a=0;
char ch[2];
if((fp=fopen("data.txt","r+"))==NULL)//只读取文件的操作 
{
 printf("不能打开文件\n");
 return;	
}
while(!feof(fp)) 
 if(fread(&stu[a],LEN,1,fp)==1)
  a++;
  fclose(fp);
if(a==0)
{
	printf("没有记录!\n");
	return;
}
printf("请输入要删除学生的学号:");
scanf("%d",&snum);
for(i=0;i<a;i++)
if(snum==stu[i].num)//判断要删除的学生的学号是否存在文件中 
break;
printf("已经找到该学生,是否删除(y/n):");
scanf("%s",ch);
if(strcmp(ch,"Y")==0||strcmp(ch,"y")==0)//判断是否要进行删除
      for(j=i;j<a;j++)
	      stu[j]=stu[j+1];//将后一个记录移到前一个记录的位置
      a--;//记录的总的学生个数将会减少1
      if((fp=fopen("data.txt","wb"))==NULL)//wb为只写,为输出的数据打开一个二进制文件 
     { 
	 printf("不能打开文件\n");
	 return;
	 }
  for(j=0;j<a;j++)//将更改后的记录重新写入指定的文件中,此时的顺序不变,和原来排序相同 
      if(fwrite(&stu[j] ,LEN,1,fp)!=1)
       { 
	   printf("不能保存!\n");
      getch();
	  }
  fclose(fp);
  printf("修改成功!\n");
  printf("请按任意键返回主菜单!\n");		
}

void revise()//根据学号来修改学生信息
{
	FILE  *fp;
	int snum,i,j,a=0;
	if((fp=fopen("data.txt","r+"))==NULL)//读取文件中的数据 
	{
		printf("不能打开文件!\n");
		return;
	}
	while(!feof(fp))  //判断文件指针是否指到文件的末尾
	if(fread(&stu[a],LEN,1,fp)==1)
	a++;
	if(a==0)
	{
		printf("没有记录!\n");
		fclose(fp);
		return;
	} 
   printf("请输入你想修改的信息的学生学号!\n");
   scanf("%d",&snum);
   for(i=0;i<a;i++)
   if(snum==stu[i].num)//匹配学号是否相同,如果学号是相同的,就进行相关信息的修改 
   break;
   printf("已经找到该学生,请进行修改!\n");
   printf("姓名:");
		scanf("%s",stu[i].name);
		printf("语文:");
		scanf("%d",&stu[i].chiness_score);
		printf("数学:");
		scanf("%d",&stu[i].math_score);
		printf("英语:");
		scanf("%d",&stu[i].english_score);
		printf("物理:");
		scanf("%d",&stu[i].wuli_score);
		stu[a].sum=stu[a].chiness_score+stu[a].math_score+stu[a].english_score+stu[a].wuli_score;
		if((fp=fopen("data.txt","wb"))==NULL)//wb为只写,为输出的数据打开一个二进制文件 
		{
			printf("不能够打开文件!\n");
			return;
		}
		for(j=0;j<a;j++)
		if(fwrite(&stu[j],LEN,1,fp)!=1)
		{
			printf("不能保存!\n");
			getch();
		}
		fclose(fp);
		printf("请按任意键返回主菜单!\n");
}

void order()//将成绩进行排序并输出 
{
	FILE *fp;
	struct student t;
	int i,j,m=0;
	if((fp=fopen("data.txt","r+"))==NULL)//读取学生文件 
	{
		printf("不能够打开文件!\n");
		return;
	}	
	while(!feof(fp))
	if(fread(&stu[m],LEN,1,fp)==1)
	m++;
	fclose(fp);
	if(m==0)
	{
		printf("没有记录!\n");
		return;
	}
	if((fp=fopen("data.txt","wb"))==NULL)//wb为只写,为输出的数据打开一个二进制文件 
	{
	printf("不能打开文件!\n");
	return;
	}
	for(i=0;i<m-1;i++)
	for(j=i+1;j<m;j++)
	if(stu[i].sum<stu[j].sum)
	{
		t=stu[i];
		stu[i]=stu[j];
		stu[j]=t;
	}
	if((fp=fopen("data.txt","wb"))==NULL)//wb为只写,为输出的数据打开一个二进制文件 
	{
		printf("不能打开!\n");
		return; 
	}
	for(j=0;j<m;j++)
	if(fwrite(&stu[j],LEN,1,fp)!=1)
       { 
        printf("%s不能保存!\n"); 
        getch();
      }
  fclose(fp);
  show();
  printf("请按任意键返回主菜单!\n");
}
void number()//统计学生数量 
{
  FILE *fp;
  int m=0;
  if((fp=fopen("data.txt","r+"))==NULL)//读取文件中的数据 
  {
  	printf("不能够打开文件!\n");
  	return;
  }	
  while(!feof(fp))
  if(fread(&stu[m],LEN,1,fp)==1)
  m++;
  if(m==0)
  {
  	printf("不能够记录!\n");
  	fclose(fp);
  	return;
  }
  printf("这个班共有%d个学生!\n",m);
  fclose(fp);
  printf("请按任意键返回主菜单!\n");
}

项目总结

(1)总体功能:
该系统的总体功能是实现的是学生信息的管理,保存学生的基本信息,包括学号、姓名、班级、语文成绩、数学成绩、英语成绩、物理成绩以及总成绩这些数据,在这个学生信息管理系统中具体可实现的操作有:1、创建学生信息文件,根据提示输入学生的各项信息;2、增加学生信息,在原有学生信息文件的基础上增加新的学生成绩信息;3、删除学生信息;4、修改学生信息;5、查询学生信息,并且按照总分排序和输出,并且进行系统中学生人数的基本统计分析。
(2)不足之处:
1、没有使用动态的数组或者是链表来实现,而是用了一个数组来盛放所有的数据,占用系统内存过大,没有合理释放数组空间。
2、四门学科的成绩单独用变量来表示,没有将其放在数组中,操作起来过程有些繁琐,没有像放在数组中的简洁明了。
3、具体实现的统计模块的功能简单,只能统计系统中学生的人数,以及按照学生的各科总分进行排序输出。
(3)进一步改进方向:
1、使用链表,动态分配内存空间,不过多占用系统的内存资源,保证资源的随时释放。
2、在统计信息模块,增加平均分、各科单独成绩综合的排序输出模块,从而使最终的系统功能更加丰富,统计的功能更加多。
(4)开发心得:
1、通过此次的项目,了解了基本的文件操作,知道怎样向文件中写入数据,并且将文件中的数据进行储存,知道怎样通过二进制的方法进行文件读写。
2、加深了解链表的基本知识,以及动态数组的实现,在此过程中,知道一个程序要尽可能少的占用系统内存资源。

补充:动态数组类

#include <stdio.h>
#include <stdlib.h>
#define SIZE_BLOCK 5
//动态数组类 
class  rArray
{

	int *data;
	int size;//0
	int max_size;//10
public:
	//创建动态数组
	rArray(int array_size);
	//释放动态数组 
	~rArray( );
	//获取动态数组中元素个数
	int get_size( );
	//获取动态数组大小 
	int get_maxsize( );
	//增大数组 
	void growth(int growth_size);
	//获取、设置动态数组元素 
	int* at_value(int index);
	//输出数组元素
	void output();

};

//构造函数:创建动态数组
rArray::rArray(int array_size)
{
	//rArray arr;
	size = 0;
	max_size = array_size;
	data = (int *)malloc(sizeof(int)*array_size);
	for(int i=0;i<max_size;i++)
		data[i]=0; 
}
//析构函数
rArray::~rArray( )
{
	free(data);
	data = NULL;
	size = 0;
	max_size = 0;
}

//获取动态数组中元素个数
int rArray::get_size()
{
	return size;
}

//获取动态数组大小 
int rArray::get_maxsize()
{
	return max_size;
}

//增大数组 
void rArray::growth(int growth_size)//5 
{
	printf("数组长度不够,增加长度:%d",growth_size);
	int *p;
	max_size += growth_size;
	p=(int *)malloc(sizeof(int)*(max_size));
	int i;
	for(i=0;i<size;i++)
	{
		p[i] = data[i];
	} 
	free(data);
	data = p;		 
}

//获取、设置动态数组元素 
int* rArray::at_value(int index)//index=10
{
	size++;
	if(index >= max_size)
	{
		growth(SIZE_BLOCK);
	}
	return &(data[size-1]);
}

void rArray::output()
{
	int i;
	for(i=0;i<size;i++)
		printf("%5d",data[i]);
	printf("\n");
}

int main()
{
	rArray arr(10);
	printf("数组原始大小:%d,数组中元素个数:%d\n",arr.get_maxsize(),arr.get_size());
	int number,count=0;
	printf("向数组里输入数据(-1结束)\n");
	do
	{
		scanf("%d",&number);//110
		if(number!=-1)
			*(arr.at_value(count++))=number;//count=10
	}while(number!=-1);
	printf("当前数组大小:%d,数组中元素的个数%d\n",arr.get_maxsize(),arr.get_size());
	printf("数组数据:");
	arr.output();
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值