用C语言写一个学生成绩管理系统(链表、文件)

这是我在大一上学期写过的最长的代码,写一个博客作为纪念也供大家参考,有错误的地方还请指正。

一、功能实现

这个系统分为对数据进行操作和对数据进行统计两个部分。

可以对数据进行的操作有创建文件、添加数据、修改数据和删除数据。可以对数据进行的统计有打印所有学生信息、按关键字查找和按分数段查找。

二、思路和具体操作

首先需要说明的是,这个系统是作为一个包含三个源文件的C语言工程编写的。其中主目录和二级目录一个文件,数据操作为一个文件,数据统计为一个文件。

1.目录

在这里把系统主目录和二级目录的代码贴出来

#include <stdio.h>
#include <stdlib.h>
void MENU(void);
void ScoreManagement(void);
void ScoreStatistics(void);

int main(int argc, char *argv[]) {
	MENU();
}

void MENU(void){
	fflush(stdin);
	int a;
	printf("                     MENU\n");
	printf("Enter the number before the option to continue\n");
	printf("             [1] Score Management\n");
	printf("             [2] Score Statistics\n");
	printf("             [3] Exit\n");
	a=getche();
	if(a=='1'){
		puts("");
		ScoreManagement();
	}else if(a=='2'){
		puts("");
		ScoreStatistics();
	}else if(a=='3'){
		exit(1);
	}else{
		printf("WRONG!\n");
		MENU();
	}
}

void ScoreManagement(void){
	fflush(stdin);
	int a1;
	printf("               Score Management\n");
	printf("Enter the number before the option to continue\n");
	printf("             [1] Creat New File\n");
	printf("             [2] Score Addition\n");
	printf("             [3] Score Deletion\n");
	printf("             [4] Score Revision\n");
	printf("             [5] Back to MENU\n");
	a1=getche();
	if(a1=='1'){
		puts("");
		CREAT();
	}else if(a1=='2'){
		puts("");
		ADDITION();
	}else if(a1=='3'){
		puts("");
		DELETION();
	}else if(a1=='4'){
		puts("");
		REVISECHOOSE();
	}else if(a1=='5'){
		puts("");
		MENU();
	}
}

void ScoreStatistics(void){
	fflush(stdin);
	int a2;
	printf("               Score Statistics\n");
	printf("Enter the number before the option to continue\n");
	printf("             [1] Score Query\n");
	printf("             [2] Score Statistics\n");
	printf("             [3] Back to MENU\n");
	a2=getche();
	if(a2=='1'){
		puts("");
		QUERY();
	}else if(a2=='2'){
		puts("");
		STATISTICS();
	}else if(a2=='3'){
		puts("");
		MENU();
	}
}

2.数据操作

在编写函数之前首先对所需要的头文件、函数和结构体进行声明

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lenID 20
#define lenname 20
#define lenmath 4
#define lenEnglish 4
#define lenprogram 4
void CREAT(void);
void ADDITION(void);
void DELETION(void);
void REVISECHOOSE(void);
struct student *READ(FILE *fp);
void WRITE(struct student *head,FILE* fp);
struct student *READ(FILE *fp);
void REVISE(struct student *p);
struct student{
	char ID[20];
	char name[20];
	char math[4];
	char English[4];
	char program[4];
	struct student *next;
};

① 创建文件

首先把这一部分的代码贴出来

void CREAT(void){//新建文件 
	char path[100]={0};
	char c,d;
	FILE *fp=NULL;//以上为变量声明 
	printf("Enter the file path:");
	gets(path); 
	if(access(path,0)==0){
		printf("File \"%s\" exists, override it? Enter \"Y\" to override, \"N\" to exit.\n",path);
		c=getche();
		puts("");
		if(c!='Y'){
			ScoreManagement();
		}
	}//检查文件是否存在 
	fp=fopen(path,"wb");
	printf("Enter student's ID, NAME, MATH SCORE, ENGLISH SCORE, PROGRAM SCORE, press ENTER to enter next item.\n");
	do{
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		printf("ID:");
		gets(ID);
		fwrite(ID,lenID,1,fp);
		fflush(stdin);
		printf("Name:");
		gets(name);
		fwrite(name,lenname,1,fp);
		fflush(stdin);
		printf("math:");
		gets(math);
		fwrite(math,lenmath,1,fp);
		fflush(stdin);
		printf("English:");
		gets(English);
		fwrite(English,lenEnglish,1,fp);
		fflush(stdin);
		printf("program:");
		gets(program);
		fwrite(program,lenprogram,1,fp);
		fflush(stdin);
		printf("Press ENTER to continue, press other key to quit.\n");
		d=getche();
		puts("");
	}while(d=='\r');//输入学生信息 
	fclose(fp);
	puts("");
	printf("Cread successfully!\n");
	ScoreManagement();
}

这里需要注意的是检查创建的文件是否已经存在,并给用户是否需要覆盖的选项。
用户每输入完一组数据后需要再按一次回车来进行下一位学生信息的输入,如果输入的内容不为“回车”则停止输入,后面的许多操作都是类似的。

② 修改数据

以下为添加数据的代码,与创建文件的方式类似,这里不再赘述。

void ADDITION(void){//添加学生信息 
	struct student *head=NULL;
	struct student *nodenew;
	head=(struct student *)malloc(sizeof(struct student));
	char path[100];
	char c,d;
	FILE *fp=NULL;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		ScoreManagement();
	}//检查文件是否存在 
	fp=fopen(path,"ab");
	printf("Enter student's ID, NAME, MATH SCORE, ENGLISH SCORE, PROGRAM SCORE, press ENTER to enter next item.\n");
	do{
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		printf("ID:");
		gets(ID);
		fwrite(ID,lenID,1,fp);
		fflush(stdin);
		printf("Name:");
		gets(name);
		fwrite(name,lenname,1,fp);
		fflush(stdin);
		printf("math:");
		gets(math);
		fwrite(math,lenmath,1,fp);
		fflush(stdin);
		printf("English:");
		gets(English);
		fwrite(English,lenEnglish,1,fp);
		fflush(stdin);
		printf("program:");
		gets(program);
		fwrite(program,sizeof(lenprogram),1,fp);
		fflush(stdin);
		printf("Press ENTER to continue, press other key to quit.\n");
		d=getche();
		puts("");
	}while(d=='\r');//输入学生信息 
	puts("");
	fclose(fp);//关闭 
	printf("Add successfully!\n"); 
	ScoreManagement();
}

③ 删除数据

接下来就是这个系统里我认为比较难或者说综合性比较强的一部分了。
删除数据分为这样四步:

创建链表
查找数据
删除数据
数据重写

在第一步创建链表部分由于使用频率比较高,因此我写了一个单独的READ函数,代码如下:

struct student *READ(FILE *fp){
	int i;
	struct student *head=NULL;
	struct student *nodenew;
	struct student *nodepre;
	nodenew=(struct student *)malloc(sizeof(struct student));
	nodepre=(struct student *)malloc(sizeof(struct student));
	nodenew->next=NULL;
	nodepre->next=NULL;
	char ID[20]={0};
	char name[20]={0};
	char math[4]={0};
	char English[4]={0};
	char program[4]={0};
	fread(ID,lenID,1,fp);
	for(i=0;i<lenID;i++){
		nodenew->ID[i]=ID[i];
	}
	fread(name,lenname,1,fp);
	for(i=0;i<lenname;i++){
		nodenew->name[i]=name[i];
	}
	fread(math,lenmath,1,fp);
	for(i=0;i<lenmath;i++){
		nodenew->math[i]=math[i];
	}
	fread(English,lenEnglish,1,fp);
	for(i=0;i<lenEnglish;i++){
		nodenew->English[i]=English[i];
	}
	fread(program,lenprogram,1,fp);
	for(i=0;i<lenprogram;i++){
		nodenew->program[i]=program[i];
	}
	nodenew->next=NULL;
	head=nodenew;
	nodepre=head;
	while(!feof(fp)){
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		nodenew=(struct student *)malloc(sizeof(struct student));
		fread(ID,lenID,1,fp);
		for(i=0;i<lenID;i++){
			nodenew->ID[i]=ID[i];
		}
		fread(name,lenname,1,fp);
		for(i=0;i<lenname;i++){
			nodenew->name[i]=name[i];
		}
		fread(math,lenmath,1,fp);
		for(i=0;i<lenmath;i++){
			nodenew->math[i]=math[i];
		}
		fread(English,lenEnglish,1,fp);
		for(i=0;i<lenEnglish;i++){
			nodenew->English[i]=English[i];
		}
		fread(program,lenprogram,1,fp);
		for(i=0;i<lenprogram;i++){
			nodenew->program[i]=program[i];
		}
		nodenew->next=NULL;
		nodepre->next=nodenew;
		nodepre=nodenew;
	}
	return head;
}

使用这个函数需要将需要读取的文件传入此函数,然后这个函数会创建一个链表并返回这个链表的头指针。这里我用的是尾插法,以保证数据的顺序与用户输入时的顺序相同。
使用!feof(fp)作为终止条件时会出现最后多读一次的情况,这里我已经做了处理解决了这个问题。这个问题的具体原因和解决方法详见feof多读一次数据的问题
由于我定义的链表中的变量全部为字符数组,所以只能一个字符一个字符地把数据读到链表内。

下面是删除函数本体

void DELETION(void){//删除学生信息 
	struct student *head=NULL;
	struct student *p;
	p=(struct student *)malloc(sizeof(struct student));
	head=(struct student *)malloc(sizeof(struct student));
	char ID[20]={0};
	char name[20]={0};
	char path[100]={0};
	char c;
	FILE *fp;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		ScoreManagement();
	}//检查文件是否存在 
	fp=fopen(path,"rb");
	head=READ(fp);
	printf("Enter the number before the option to contiune.\n");
	printf("[1] Delete by ID\n");
	printf("[2] Delete by NAME\n");
	c=getche();
	puts("");//选择删除查找依据 
	p=head;
	if(c=='1'){//依据ID删除 
		printf("Enter the student's ID you want to delete:");
		gets(ID);
		while(p->next!=NULL){
			if((strcmp(ID,p->ID)==0)&&(p==head)){
				head=p->next;
				break;
			}else if(strcmp(ID,(p->next)->ID)==0){
				p->next=(p->next)->next;
				break;
			}
			p=p->next;
			if(p->next==NULL){
				printf("NOT EXIST!\n");
			}
		}
	}else if(c=='2'){
		printf("Enter the student's name you want to delete:");
		gets(name);
		while(p!=NULL){
			if((strcmp(name,p->name)==0)&&(p==head)){
				head=p->next;
				break;
			}else if(strcmp(name,(p->next)->name)==0){
				p->next=(p->next)->next;
				break;
			}
			p=p->next;
			if(p->next==NULL){
				printf("NOT EXIST!\n");
			}
		}//依据姓名删除 
	}else{
		printf("WRONG!\n");
		fclose(fp);
		ScoreManagement();
	}//选择时输入错误 
	fp=fopen(path,"wb");
	p=head;
	while(p->next!=NULL){
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		strcpy(ID,p->ID);
		fwrite(ID,lenID,1,fp);
		strcpy(name,p->name);
		fwrite(name,lenname,1,fp);
		strcpy(math,p->math);
		fwrite(math,lenmath,1,fp);
		strcpy(English,p->English);
		fwrite(English,lenEnglish,1,fp);
		strcpy(program,p->program);
		fwrite(program,lenprogram,1,fp);
		p=p->next;
	}
	fclose(fp);//关闭 
	printf("Delete successfully!");
	ScoreManagement();
}

这里给了用户两个选项,分别为按照姓名查找删除和按照ID查找删除。
查找数据所需要的链表遍历和删除数据所需要的链表删除都在函数中有所体现。
需要注意到删除时对头部删除的特殊性。
如果没有查找到用户需要的姓名或ID,需要给予反馈。
完成操作后再把链表内的数据重新写入到文件内,这里注意一下文件的打开方式。

④ 修改数据

修改数据与删除数据方法类似,也是四步走:

创建链表
查找数据
修改数据
数据重写

为了实现这个功能我写了两个函数。一个函数是主函数,用于选择以哪种方式查找需要修改的数据(姓名、ID)并在修改完成后把链表中的内容重新写到文件内。另一个函数用来让用户选择修改哪项数据,读取用户输入的新数据并做修改。

下面是这两个函数

主函数

void REVISECHOOSE(void){
	struct student *head=NULL;
	struct student *p;
	p=(struct student *)malloc(sizeof(struct student));
	head=(struct student *)malloc(sizeof(struct student));
	FILE *fp;
	char path[100];
	char name[20];
	char ID[20];
	char c;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		ScoreManagement();
	}//检查文件是否存在 
	fp=fopen(path,"rb");
	head=READ(fp);
	printf("Enter the number before the option to contiune.\n");
	printf("[1] Search by ID\n");
	printf("[2] Search by NAME\n");
	c=getche();
	puts("");
	p=head;
	if(c=='1'){
		printf("Enter the student's ID you want to revise:");
		gets(ID);
		while(p->next!=NULL){
			if(strcmp(p->ID,ID)==0){
				REVISE(p);
				break;
			}
			p=p->next;
			if(p->next==NULL){
				printf("NOT EXIST!\n");
			}
		}//按ID检索 
	}else if(c=='2'){
		printf("Enter the student's name you want to revise:");
		gets(name);
		while(p->next!=NULL){
			if(strcmp(p->name,name)==0){
				REVISE(p);
			}
			p=p->next;
			if(p->next==NULL){
				printf("NOT EXIST!\n");
			}
		}//按姓名检索 
	}else{
		printf("WRONG!\n");
		fclose(fp);
		QUERY();
	}//选择错误
	fp=fopen(path,"wb");
	p=head;
	while(p->next!=NULL){
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		strcpy(ID,p->ID);
		fwrite(ID,lenID,1,fp);
		strcpy(name,p->name);
		fwrite(name,lenname,1,fp);
		strcpy(math,p->math);
		fwrite(math,lenmath,1,fp);
		strcpy(English,p->English);
		fwrite(English,lenEnglish,1,fp);
		strcpy(program,p->program);
		fwrite(program,lenprogram,1,fp);
		p=p->next;
	}
	fclose(fp);
	ScoreManagement();
}

修改函数

void REVISE(struct student *p){
	int i;
	char a14=0;
	printf("Enter the number before the option to continue\n");
	printf("[1] Revise ID\n");
	printf("[2] Revise name\n");
	printf("[3] Revise math score\n");
	printf("[4] Revise English score\n");
	printf("[5] Revise program score\n");
	a14=getche();
	puts("");
	if(a14=='1'){
		char newID[20];
		printf("Enter new ID:");
		gets(newID);
		for(i=0;i<lenID;i++){
			p->ID[i]=newID[i];
		}
	}else if(a14=='2'){
		char newname[20];
		printf("Enter new name:");
		gets(newname);
		for(i=0;i<lenname;i++){
			p->name[i]=newname[i];
		}
	}else if(a14=='3'){
		char newmath[4];
		printf("Enter new math score:");
		gets(newmath);
		for(i=0;i<lenmath;i++){
			p->math[i]=newmath[i];
		}
	}else if(a14=='4'){
		char newEnglish[4];
		printf("Enter new English score:");
		gets(newEnglish);
		for(i=0;i<lenEnglish;i++){
			p->English[i]=newEnglish[i];
		}
	}else if(a14=='5'){
		char newprogram[4];
		printf("Enter new program score:");
		gets(newprogram);
		for(i=0;i<lenprogram;i++){
			p->program[i]=newprogram[i];
		}
	}
}

至此,数据修改部分就全部完成了。

3. 数据统计

这一部分比较简单,大家看看就好。

首先依然是对所需头文件、函数和结构体的声明

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define lenID 20
#define lenname 20
#define lenmath 4
#define lenEnglish 4
#define lenprogram 4
void QUERY(void); 
void PRINTALL(void);
void SEARCH(void);
void STATISTICS(void);
void STATISTICSMATH(void);
void STATISTICSENGLISH(void);
void STATISTICSPROGRAM(void);
struct student{
	char ID[20];
	char name[20];
	char math[4];
	char English[4];
	char program[4];
	struct student *next;
};

为了方便查找,我又做了三级目录

void QUERY(void){
	fflush(stdin);
	int a21;
	printf("Enter the number before the option to contine.\n");
	printf("[1] Print All Information\n");
	printf("[2] Keyword Search\n");
	printf("[3] Back to Score Statistics\n");
	a21=getche();
	if(a21=='1'){
		puts("");
		PRINTALL();
	}else if(a21=='2'){
		puts("");
		SEARCH();
	}else if(a21=='3'){
		puts("");
		ScoreStatistics();
	}else{
		printf("WRONG!\n");
		MENU();
	}
}

① 打印全部数据

这一部分比较简单,一个fread就足够了,依然注意使用!feof(fp)带来的问题。

void PRINTALL(void){//输出所有学生信息 
	char path[100];
	char c;
	FILE *fp;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	puts("");
	if(access(path,0)==-1){
		printf("NOT EXIST!");
	}//判断文件是否存在 
	fp=fopen(path,"rb");
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		fread(ID,lenID,1,fp);
		fread(name,lenname,1,fp);
		fread(math,lenmath,1,fp);
		fread(English,lenEnglish,1,fp);
		fread(program,lenprogram,1,fp);
	while(!feof(fp)){
		printf("ID:%s\t Name:%s\t Math:%s\t English:%s\t Program:%s\t\n",ID,name,math,English,program);
		fread(ID,lenID,1,fp);
		fread(name,lenname,1,fp);
		fread(math,lenmath,1,fp);
		fread(English,lenEnglish,1,fp);
		fread(program,lenprogram,1,fp);
	}
	//输出学生信息 
	fclose(fp);
	printf("Press any key to contine.");
	c=getche();
	if(c!=0){
		ScoreStatistics();
	}
}

② 查找学生信息

这个功能其实已经包含在删除和添加数据功能内部了,代码如下

void SEARCH(void){//查找学生信息 
	struct student *head=NULL;
	struct student *p;
	p=(struct student *)malloc(sizeof(struct student));
	head=(struct student *)malloc(sizeof(struct student));
	FILE *fp;
	char path[100];
	char name[20]={0};
	char ID[20]={0};
	char c;//以上为变量声明 
	printf("Enter the file name:");
	fflush(stdin);
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		ScoreManagement();
	}//检查文件是否存在 
	fp=fopen(path,"rb");
	head=(struct student *)READ(fp);
	printf("Enter the number before the option to contiune.\n");
	printf("[1] Search by ID\n");
	printf("[2] Search by NAME\n");
	c=getche();
	puts("");
	p=head;
	if(c=='1'){
		printf("Enter the student's ID you want to search:");
		fflush(stdin);
		gets(ID);
		while(p->next!=NULL){
			if(strcmp(p->ID,ID)==0){
				printf("%ID:%s\t Name:%s\t Math:%s\t English:%s\t Program:%s\t\n",p->ID,p->name,p->math,p->English,p->program);
				break;
			}
			p=p->next;
			if(p->next==NULL){
				printf("NOT EXIST!\n");
			}
		}//按ID检索 
	}else if(c=='2'){
		printf("Enter the student's name you want to search:");
		fflush(stdin);
		gets(name);
		while(p->next!=NULL){
			if(strcmp(p->name,name)==0){
				printf("ID:%s\t Name:%s\t Math:%s\t English:%s\t Pogram:%s\t\n",p->ID,p->name,p->math,p->English,p->program);
				break;
			}
			p=p->next;
			if(p->next==NULL){
				printf("NOT EXIST!\n");
			}
		}//按姓名检索 
	}else{
		printf("WRONG!\n");
		fclose(fp);
		QUERY();
	}//选择错误 
	fclose(fp);
	QUERY();
}

③ 分数段统计

同样简单的功能,只不过由于我的所有数据都是以字符形式储存的,因此在数据比较时需要把字符变量转化为数据。

下面是代码,由于有三门可以统计的科目,因此有三段相同的代码,不过是科目不同罢了。

void STATISTICS(void){//分数段统计 
	fflush(stdin);
	int a22;
	printf("Enter the number before the option to continue\n");
	printf("[1] Statistics by Math Score\n");
	printf("[2] Statistics by English Score\n");
	printf("[3] Statistics by Program\n");
	printf("[4] Back to Score Statistics\n");
	a22=getche();
	if(a22=='1'){
		puts(""); 
		STATISTICSMATH();
	}else if(a22=='2'){
		puts("");
		STATISTICSENGLISH();
	}else if(a22=='3'){
		puts("");
		STATISTICSMATH();
	}else if(a22=='4'){
		puts("");
		ScoreStatistics();
	}else{
		MENU();
	}
}

void STATISTICSMATH(void){
	int mathtrue,i,len;
	int max=0,min=0;
	char path[100];
	FILE *fp;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		STATISTICSMATH();
	}//检查文件是否存在 
	printf("Enter the score range you want to query.\n");
	printf("e.g. \"60 70\" to query score that greater than or equal to 60 and less than or equal to 70.\n");
	scanf("%d %d",&min,&max);
	fp=fopen(path,"rt");
	while(!feof(fp)){
		char MATH[4]={0};
		mathtrue=0;
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		fread(ID,lenID,1,fp);
		fread(name,lenname,1,fp);
		fread(math,lenmath,1,fp);
		fread(English,lenEnglish,1,fp);
		fread(program,lenprogram,1,fp);
		len=strlen(math);
		for(i=0;i<len;i++){
			MATH[len-i-1]=math[i]-48;
		}
		for(i=0;i<len;i++){
			mathtrue=mathtrue+MATH[i]*pow(10,i);
		}
		if((mathtrue>=min)&&(mathtrue<=max)){
			printf("ID:%s\t Name:%s\t Math:%s\t English:%s\t Program:%s\t\n",ID,name,math,English,program);
		}//输出学生信息
	}
	fclose(fp);
	STATISTICS();
}

void STATISTICSENGLISH(void){
	int Englishtrue,i,len;
	int max=0,min=0;
	char path[100];
	FILE *fp;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		STATISTICSMATH();
	}//检查文件是否存在 
	printf("Enter the score range you want to query.\n");
	printf("e.g. \"60 70\" to query score that greater than or equal to 60 and less than or equal to 70.\n");
	scanf("%d %d",&min,&max);
	fp=fopen(path,"rt");
	while(!feof(fp)){
		char ENGLISH[4]={0};
		Englishtrue=0;
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		fread(ID,lenID,1,fp);
		fread(name,lenname,1,fp);
		fread(math,lenmath,1,fp);
		fread(English,lenEnglish,1,fp);
		fread(program,lenprogram,1,fp);
		len=strlen(English);
		for(i=0;i<len;i++){
			ENGLISH[len-i-1]=math[i]-48;
		}
		for(i=0;i<len;i++){
			Englishtrue=Englishtrue+ENGLISH[i]*pow(10,i);
		}
		if((Englishtrue>=min)&&(Englishtrue<=max)){
			printf("ID:%s\t Name:%s\t Math:%s\t English:%s\t Program:%s\t\n",ID,name,math,English,program);
		}//输出学生信息
	}
	fclose(fp);
	STATISTICS();
}

void STATISTICSPROGRAM(void){
	int programtrue,i,len;
	int max=0,min=0;
	char path[100];
	FILE *fp;//以上为变量声明 
	printf("Enter the file name:");
	gets(path);
	if(access(path,0)==-1){
		printf("NOT EXIST!\n");
		STATISTICSMATH();
	}//检查文件是否存在 
	printf("Enter the score range you want to query.\n");
	printf("e.g. \"60 70\" to query score that greater than or equal to 60 and less than or equal to 70.\n");
	scanf("%d %d",&min,&max);
	fp=fopen(path,"rt");
	while(!feof(fp)){
		char PROGRAM[4]={0};
		programtrue=0;
		char ID[20]={0};
		char name[20]={0};
		char math[4]={0};
		char English[4]={0};
		char program[4]={0};
		fread(ID,lenID,1,fp);
		fread(name,lenname,1,fp);
		fread(math,lenmath,1,fp);
		fread(English,lenEnglish,1,fp);
		fread(program,lenprogram,1,fp);
		len=strlen(program);
		for(i=0;i<len;i++){
			PROGRAM[len-i-1]=program[i]-48;
		}
		for(i=0;i<len;i++){
			programtrue=programtrue+PROGRAM[i]*pow(10,i);
		}
		if((programtrue>=min)&&(programtrue<=max)){
			printf("ID:%s\t Name:%s\t Math:%s\t English:%s\t Program:%s\t\n",ID,name,math,English,program);
		}//输出学生信息
	}
	fclose(fp);
	STATISTICS();
}

以上就是数据统计部分了。

  • 13
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言学生成绩管理系统(以包含文件的形式的),结构体,链表,数组,以下是main.c #include #include #include #define m 3/*宏定义m的值为3*/ struct node/*链表初始化*/ { char name[20]; int no; float score[m]; float sum; float avg; struct node *next; }; char ch[m+4][20]={{"学号"},{"姓名"},{"语文"},{"数学"},{"英语"},{"总分"},{"平均分"}};/*定义并初始化一个全局二维字符数组*/ #include "save.c"/*包含保存文件*/ #include "read.c"/*包含读取文件*/ #include "output.c"/*包含打印文件*/ #include "set.c"/*包含录入文件*/ #include "demand.c"/*包含查询文件*/ #include "sort.c"/*包含排序文件*/ #include "modified.c"/*包含修改文件*/ #include "add.c"/*包含添加文件*/ #include "del.c"/*包含删除文件*/ void main() { int n; printf("\n\t\t\t欢迎使用学生成绩管理系统\n\n"); printf("\t\t\t\t\t\t制 作: XIA XIA\n"); do { printf("\n\n1:学生成绩录入,并保存\n"); printf("2:学生成绩查询\n"); printf("3:学生成绩的排序\n"); printf("4:学生成绩的修改\n"); printf("5:学生成绩的打印\n"); printf("6:学生信息的添加\n"); printf("7:学生信息的删除\n"); printf("0:退出学生成绩管理系统\n\n\n"); printf("输入你要执行操作的相应序号\n"); scanf("%d",&n);/*输入相就的操作的序号*/ switch (n) { case 1: set();break;/*调用录入函数*/ case 2: demand();break;/*调用查询函数*/ case 3: sort();break;/*调用排序函数*/ case 4: modified();break;/*调用修改函数*/ case 5: output();break;/*调用打印函数*/ case 6: add();break;/*调用添加函数*/ case 7: del();break;/*调用删除函数*/ case 0: printf("正在退出学生成绩管理系统......\n");exit(0);/*直到输入“0”退出学生成绩管理系统*/ default:printf("输入错误码,请重新输入\n"); } }while(1); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值