单链表模拟学生成绩管理系统(利用文件输入输出)

模拟学生成绩管理系统。

现有若干学生的学籍档案信息,要求编写一个应用软件对其进行日常管理,以实现学生档案信息的插入和删除,并能根据学生姓名查询。(使用文件作为数据的输入/输出,准备若干测试数据以文件形式保存或读取。)
源代码如下:
(文件路径:D:\Student.txt)

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
typedef struct student
{
	char Name[20];
	int Num;
	char Sex;
	int Chinese;
	int Math;
	int English;
	int Add;
	float Aver;
}stu;        //学生信息与成绩数据

typedef struct node
{
	stu data;
	struct node *next;
}linklist;    //单链表结构体

void MainMenu()
{
	char choice;
	void Input();
	void Delete();
	void Locate();
	printf("请从下面的菜单中选择您要进行的操作:\n\n");
	printf("**********************\n");
	printf("*   a.插入学生信息   *\n");
	printf("*   b.删除学生信息   *\n");
	printf("*   c.查询学生信息   *\n");
	printf("*   d.退出系统       *\n");
	printf("**********************\n\n");
	scanf("%c",&choice);
	printf("\n");
	switch(choice)
	{
	case'a':Input();break;
	case'b':Delete();break;
	case'c':Locate();break;
	case'd':{
		printf("**********学生信息管理系统**********\n");
		printf("*                                  *\n");
		printf("*  感谢您的使用,欢迎您的下次使用! *\n");
		printf("*                                  *\n");
		printf("**********程序设计综合实验**********\n\n");
		break;
			}
	default:{
		printf("抱歉!未开通此项服务。请您重新选择:\n\n");
		MainMenu();
			}
	}
}

linklist *Read()
{
	linklist *head,*r,*s;
	head=(linklist*)malloc(sizeof(linklist));
	r=head;
	FILE *fp;
	if((fp=fopen("D:\\Student.txt","rb"))==NULL)
	{
		printf("文件打开失败!请检查文件所处路径是否正确。\n");
		exit(0);
	}
	fseek(fp,59L,0);
	while(!feof(fp))
	{
		s=(linklist*)malloc(sizeof(linklist));
		fscanf(fp,"%s %d %c %d %d %d %d %f",s->data.Name,&s->data.Num,&s->data.Sex,&s->data.Chinese,&s->data.Math,&s->data.English,&s->data.Add,&s->data.Aver);
		r->next=s;
		r=s;	
	}
	r->next=NULL;
	fclose(fp);
	return head;
}     //将学生信息从文件中读取,并存储在一个单链表中

void Print(linklist *head)
{
	linklist *s;
	int i,n;
	char str[10][20],ch;
	printf("请输入您想查询的学生个数:");
	scanf("%d",&n);
	printf("请输入您想查询的学生姓名(每行输入一个):\n");
	for(i=0;i<n;i++)
		scanf("%s",str[i]);
	printf("\n");
	printf("Name             Number     Sex  Chinese  Math  English  Add  Aver\n");
	for(i=0;i<n;i++)
	{
		s=head->next;
		while(s!=NULL)
		{
			if(strcmp(str[i],s->data.Name)==0)
			{
				printf("%-17s%-12d%c     ",s->data.Name,s->data.Num,s->data.Sex);
				printf("%-8d%-7d%-7d%-5d%.1f\n",s->data.Chinese,s->data.Math,s->data.English,s->data.Add ,s->data.Aver);
				break;     //将学生信息打印到屏幕上
			}
			else
				s=s->next;
		}
		if(s==NULL)
			printf("抱歉!表中没有%s同学的信息,请检查姓名是否输入正确。\n",str[i]);
	}
	printf("\n\n接下来你希望:\n\n");
	printf("a.继续当前操作\n");
	printf("b.返回主菜单\n\n");
	getchar();    //用来消化最后输入的回车符
	while(scanf("%c",&ch)!=('a'||'b'))
		printf("抱歉!未开通此项服务。请您重新选择:\n\n");
	printf("\n");
	if(ch=='a')
		Print(head);
	else if(ch=='b')
		getchar();
		MainMenu();
}    //在屏幕上打印出学生信息数据

void save(linklist *head)
{
	char str[]={"Name        Number  Sex  Chinese  Math  English  Add  Aver\n"};
	FILE *fp;
	linklist *s;
	s=head->next;
	if((fp=fopen("D:\\Student.txt","wb"))==NULL)
	{
		printf("文件打开失败!请检查文件所处路径是否正确。\n");
		return;
	}
	fputs(str,fp);
	while(s->next!=NULL)
	{
		fprintf(fp,"%s %d %c %d %d %d %d %.1f\n",s->data.Name,s->data.Num,s->data.Sex,s->data.Chinese,s->data.Math,s->data.English,s->data.Add,s->data.Aver);
		s=s->next;
	}
	fclose(fp);
}    //将学生数据输入指定文件中

void Input()
{
	linklist *head;
	head=Read();    //从文件中读取学生数据,存储到一个单链表中
	int i,n;
	char ch;
	linklist *p,*r,*s;
	printf("请输入您要插入的学生个数:");
	scanf("%d",&n);
	printf("请按以下顺序每行输入一位插入学生信息(内容用空格分开):姓名 学号 性别 语文成绩 数学成绩 英语成绩\n");
	for(i=0;i<n;i++)
	{
		s=(linklist*)malloc(sizeof(linklist));
		scanf("%s %d %c %d %d %d",s->data.Name,&s->data.Num,&s->data.Sex,&s->data.Chinese,&s->data.Math,&s->data.English);
		if(s->data.Num>99999999||(s->data.Sex!='F'&&s->data.Sex!='M')||s->data.Chinese<0||s->data.Chinese>150||s->data.Math<0||s->data.Math>150||s->data.English<0||s->data.English>150)
		{
			i--;
			printf("请按正确格式输入!(学号为八位,性别为F或M,所有科目满分均为150):\n");
			continue;
		}     //输入格式错误时的提示
		s->data.Add=s->data.Chinese+s->data.Math+s->data.English;
		s->data.Aver=float(s->data.Add/3);
		r=head->next;
		p=head;
		while(strcmp(r->data.Name,s->data.Name)<0)   //按字母表顺序排列
		{
			p=r;
			r=r->next;
		}
		p->next=s;
		s->next=r;
	}
	save(head);    //重新写入文件
	printf("\n接下来你希望:\n");
	printf("a.继续当前操作\n");
	printf("b.返回主菜单\n\n");
	getchar();   //用来消化最后输入的回车符
	while(scanf("%c",&ch)!=('a'||'b'))
		printf("抱歉!未开通此项服务。请您重新选择:\n\n");
	printf("\n");
	if(ch=='a')
		Input();
	else if(ch=='b')
		getchar();
		MainMenu();
}     //按字母表顺序插入学生信息

void Delete()
{
	linklist *head;
	head=Read();    //从文件中读取学生数据,存储到一个单链表中
	int i,n;
	char str[10][20],ch;
	printf("请输入您要删除的学生个数:");
	scanf("%d",&n);
	printf("请输入您要删除的学生姓名(每行输入一个):\n");
	for(i=0;i<n;i++)
		scanf("%s",str[i]);
	linklist *r,*q;
	for(i=0;i<n;i++)
	{
		r=head->next;
		q=head;
		while(r!=NULL&&strcmp(str[i],r->data.Name)!=0)   //在已读取的链表中查找相同的姓名
		{
			q=r;
			r=r->next;
		}
		if(r==NULL)
			printf("\n抱歉!表中没有%s同学的信息,请检查姓名是否输入正确。\n",str[i]);
		else
		{
			q->next=r->next;
			free(r);
		}
	}
	save(head);   //重新写入文件
	printf("\n接下来你希望:\n");
	printf("a.继续当前操作\n");
	printf("b.返回主菜单\n\n");
	getchar();   //用来消化最后输入的回车符
	while(scanf("%c",&ch)!=('a'||'b'))
		printf("抱歉!未开通此项服务。请您重新选择:\n\n");
	printf("\n");
	if(ch=='a')
		Delete();
	else if(ch=='b')
		getchar();
		MainMenu();
}     //删除学生信息

void Locate()
{
	linklist *L;
	L=Read();
	Print(L);
}    //查询学生信息

int main()
{
	printf("**********学生信息管理系统**********\n");
	printf("*                                  *\n");
	printf("*             欢迎使用             *\n");
	printf("*                                  *\n");
	printf("**********程序设计综合实验**********\n\n");
	MainMenu();
	return 0;
}   //主函数

文件基本内容:
Name Number Sex Chinese Math English Add Aver
Caiyun 19180319 F 115 120 103 338 112.7
Hanmeimei 19180512 F 112 107 141 360 120.0
Lilei 19180511 M 102 113 136 351 117.0
Tengzijin 19180523 M 98 77 100 275 91.7
Wangruohan 19180101 F 125 134 135 394 131.3

由于需要,最开始文件内容全部输入后需使光标到下一行开头(实话实说算是我偷个懒哈哈)。此后的操作中皆会将末尾光标移至下一行开头,保证代码运行的正确。
文件中基本信息是按照姓名字母表顺序排列,插入信息也是按照此顺序排列的。

以下为测试样例及运行结果

1.插入信息:
Lilei 19180511 M 102 113 136

文件原信息:

在这里插入图片描述
运行结果:

在这里插入图片描述
在这里插入图片描述
输入格式错误会有提示。
插入结果:

在这里插入图片描述
插入成功。

2.删除信息:

在这里插入图片描述
删除后文件内容:

在这里插入图片描述
若查无此人也会有提示。

3.查询信息

在这里插入图片描述
在这里插入图片描述
这其实是本人大一程序设计综合实验的大作业…
能力有限,还望多多包涵!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值