模拟学生成绩管理系统。
现有若干学生的学籍档案信息,要求编写一个应用软件对其进行日常管理,以实现学生档案信息的插入和删除,并能根据学生姓名查询。(使用文件作为数据的输入/输出,准备若干测试数据以文件形式保存或读取。)
源代码如下:
(文件路径: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.查询信息
这其实是本人大一程序设计综合实验的大作业…
能力有限,还望多多包涵!