(单科成绩录入单科成绩排名,链表,文件)C语言学生管理系统

本文介绍了一个学生信息管理系统的设计与实现,包括学生信息的增删改查、成绩录入与统计等功能。系统采用C语言编写,利用链表存储数据,并支持从文件读取及保存数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


struct Student 
{
char m_strName[100];
char m_strSex[10];
char m_strNumber[100];
double m_fEnglish;
double m_fMath;
double m_fComputer;
double m_fInter;
struct Student *next;
};


void MainMenu(); //学生管理系统主菜单
void GetInformation(struct Student *human); //输入学生信息
void AddResuls(struct Student *head); //录入学生成绩
void AddInformation(struct Student **head); //新建学生信息
void PrintfInformation(struct Student *human); //打印学生信息以及成绩
void Choose(struct Student *head); //对主菜单进行处理
void SerchInformation(struct Student *head); //查找学生信息
void SerchResuls(struct Student **head); //浏览所有学生成绩
void Many(struct Student *head); //打印所有学生信息
void Change(struct Student **head); //修改学生信息
void ChangeHuman(struct Student *human); //对学生信息修改菜单进行处理
void ChangeMenu(); //修改学生信息菜单
void Delete(struct Student **head); //删除所选学生信息
void Sort(struct Student **head); //对学生各科成绩进行排序
int Compelete(struct Student *head,struct Student *human); //查找的学生信息是否录入
void Statistic(struct Student *head ); //统计成绩不符合要求人数
void ReadData (struct Student **head); //读取文件
void WriteData (struct Student *head); //保存文件
void Release(struct Student **head); //释放链表


int main()
{
struct Student *head=NULL; //建立学生信息链表的头指针

Choose(head);

return 0;
}


void MainMenu() //学生管理系统主菜单
{
printf("\t\t************欢迎来到学生管理系统************\n");
printf("\t\t     -----------------------------------\n");
printf("\t\t    |********* 1.录入学生信息 **********|\n");
printf("\t\t    |********* 2.录入学生成绩 **********|\n");
printf("\t\t    |********* 3.查询学生信息 **********|\n");
printf("\t\t    |********* 4.浏览学生成绩 **********|\n");
printf("\t\t    |********* 5.浏览全部学生情况 ******|\n");
printf("\t\t    |********* 6.修改学生信息 **********|\n");
printf("\t\t    |********* 7.删除学生信息 **********|\n");
printf("\t\t    |********* 8.统计两科以上不及格人数*|\n");
printf("\t\t    |********* 0.退出系统 **************|\n");
printf("\t\t     -----------------------------------\n");
}


void AddResuls(struct Student **head) //录入学生成绩
{
struct Student *human;
int a; //选择录入科目按钮

human = *head;
if (human==NULL)
{
printf("暂时未录入任何学生信息,请先录入学生信息!\n");
return;
}
printf("录入英语成绩**1\n");
printf("录入数学成绩**2\n");
printf("录入计算机成绩**3\n\n");
printf("请输入选项:");
scanf("%d",&a);


switch(a)
{
case 1:
printf("输入 -2 结束录入!\n");
while (human !=NULL) //判断学生成绩是否录入完毕
{

if (human->m_fEnglish>=0) //判断成绩是否已经录入,若是,则跳过该同学
{

}
else
{
printf("\t姓名:%s,",human->m_strName);
printf("学号:%s,成绩为:",human->m_strNumber);

scanf("%lf",&human->m_fEnglish);
}

if (human->m_fEnglish==-2) //判断是否要停止录入
{
return ;
}

human = human->next;
}
break;
case 2:
printf("输入 -2 结束录入!\n");
while (human !=NULL)
{

if (human->m_fMath>0)
{

}
else
{
printf("\t姓名:%s,",human->m_strName);
printf("学号:%s,成绩为:",human->m_strNumber);

scanf("%lf",&human->m_fMath);
}

if (human->m_fMath==-2)
{
return ;
}

human = human->next;
}
break;
case 3:
printf("输入 -2 结束录入!\n");
while (human !=NULL)
{

if (human->m_fComputer>0)
{

}
else
{
printf("\t姓名:%s,",human->m_strName);
printf("学号:%s,成绩为:",human->m_strNumber);

scanf("%lf",&human->m_fComputer);
}

if (human->m_fComputer==-2)
{
return ;
}

human = human->next;
}


break;
default:
printf("无效选项!\n");
break;
}
printf("您已录入所有学生成绩!\n");
}


void Choose(struct Student *head) //对主菜单进行处理
{
int input; //操作按钮存储位置

ReadData (&head); //打开文件,录入学生信息
printf("\n\n\n\n\n\n\t\t**********若要退出程序,请按提示操作!*******\n\n\n\n\n\n");
while (1)
{
MainMenu();

printf("请输入选项:");
scanf("%d",&input);

switch(input)
{
case 0:
WriteData (head);
Release(&head);
exit(0);
case 1:
AddInformation(&head);
break;
case 2:
AddResuls(&head);
break;
case 3:
SerchInformation(head);
break;
case 4:
SerchResuls(&head);
break;
case 5:
system("cls");
Many(head);
break;
case 6:
Change(&head);
break;
case 7:
Delete(&head);
break;
case 8:
Statistic(head );
break;

default:
printf ("\n无效选项!\n");
break;
}
}
}


void AddInformation(struct Student **head) //新建学生身份
{
struct Student *human;
struct Student *temp=NULL; //中间变量

human = (struct Student *)malloc(sizeof(struct Student));

if (human == NULL)
{
printf("内存分配错误!\n");
exit(1);
}

printf("请输入学生学号:");
scanf("%s",human->m_strNumber); //录入信息时先录入学号,同时判断该学生信息是否重复录入

if (Compelete(*head,human) == 0)
{
system("cls");
printf("该同学已录入信息,请重新输入!\n");
}
else
{
GetInformation(human); //录入学生的其他信息
system("cls");
PrintfInformation(human); //打印刚刚录入的学生信息
printf("该同学信息您已成功录入!\n");

if (*head ==NULL)
{
*head = human;
human->next = NULL;
}
else 
{
temp = *head;

while(temp->next!=NULL)
{
temp = temp->next;
}

temp->next = human;
human->next = NULL;
}
}
}


int Compelete(struct Student *head,struct Student *human) //判断学生信息是否存在
{
struct Student *temp; //遍历链表的中间变量
int z; //接受strcmp函数的返回值

temp=head;

while (temp!=NULL&&(z=strcmp(temp->m_strNumber,human->m_strNumber)!=0)) //将strcmp函数的返回值赋到z,方便使用
{
temp = temp->next;
}

return z;
}


void Release(struct Student **head) //释放链表
{
struct Student *p;
struct Student *q;
while ((*head)!=NULL)
{
p = *head;
q=NULL; //用来存储节点位置
for (; p!=NULL; q=p,p=p->next)
{
free(q); //释放节点
}
*head = NULL;
}
}


void GetInformation(struct Student *human)  //录入学生信息
{
printf("请输入学生姓名:");
scanf("%s",human->m_strName);
printf("请输入学生性别:");
scanf("%s",human->m_strSex);
human->m_fEnglish = -1;
human->m_fMath = -1;
human->m_fComputer = -1;
}


void PrintfInformation(struct Student *human) //打印学生信息
{
printf("姓名\t");
printf("性别\t");
printf("学号\t");
printf("英语成绩\t");
printf("数学成绩\t");
printf("计算机成绩\n");
printf("%s\t",human->m_strName); //将所有成绩赋值为-1,以便后续判断成绩是否被录入
printf("%s\t",human->m_strSex);
printf("%s\t",human->m_strNumber);
if(human->m_fEnglish<0) //判断该学生成绩是否被录入,若未被录入,则输出成绩为无
{  
printf("无\t\t");
}
else 
{
printf("%lf\t",human->m_fEnglish );
}

if (human->m_fMath<0)
{
printf("无\t\t");
}
else
{
printf("%lf\t",human->m_fMath );
}

if (human->m_fComputer < 0)
{
printf("无\n\n\n");
}
else
{
printf("%lf\n\n\n",human->m_fComputer );
}
}


void SerchInformation(struct Student *head) //查找学生信息
{
struct Student *human;
struct Student *hum; //要查找学生的学号存储位置

hum = (struct Student *)malloc(sizeof(struct Student));
human = head;

printf("请输入学生学号:");
scanf("%s",hum->m_strNumber);

while (human!=NULL) //判断该学生信息是否被录入
{
if (strcmp(human->m_strNumber,hum->m_strNumber)==0)
{
system("cls");
printf("你所查询的学生信息为:\n");
PrintfInformation(human); //打印要查找的学生信息
return;
}

human = human -> next;
}

system("cls");
printf("该学生信息不存在,请重新查找\n");
}


void SerchResuls(struct Student **head) //浏览学生成绩
{
system("cls");
Many(*head); //首先对所有学生成绩进行打印

struct Student *human;
int t; //排名菜单操作按钮存储位置

human = *head;

printf("\t\t-------------------------------\n");
printf("\t\t|  1.按英语成绩排名查看信息   |\n");
printf("\t\t|  2.按数学成绩排名查看信息   |\n");
printf("\t\t|  3.按计算机成绩排名查看信息 |\n");
printf("\t\t-------------------------------\n\n");
printf("请输入选项:");
scanf("%d",&t);

switch(t)
{
case 1:
while (human!=NULL) //在三个case下面用到了三个while循环,目的是:通过选项操作将所需要查看排名的成绩赋值给中间变量,方便传入函数进行操作
{
human->m_fInter = human->m_fEnglish;
human = human->next;
}
Sort(head); //排序
break;
case 2:
while (human!=NULL)
{
human->m_fInter = human->m_fMath;
human = human->next;
}
Sort(head); //排序
break;
case 3:
while (human!=NULL)
{
human->m_fInter = human->m_fComputer;
human = human->next;
}
Sort(head); //排序
break;
default :
printf("无效选项!\n");
break;
}
}


void Sort(struct Student **head) //对学生成绩进行排序
{
struct Student *endpt; //保存排序位置
struct Student *p; //中间变量
struct Student *p1,*p2; //遍历链表所需变量

p1 = (struct Student *) malloc (sizeof(struct Student));
p1->next = *head; //在头结点前面建立节点
*head = p1;

if (p1->next==NULL) //判断链表是否创建
{
printf("\n暂时没有学生信息!\n");
return ;
}

for (endpt = NULL; endpt != *head; endpt = p)
{
for (p = p1 = *head; p1->next->next != NULL; p1 = p1->next)
{
if (p1->next->m_fInter < p1->next->next->m_fInter)   //比较大小,交换节点
{
p2 = p1->next->next;     
p1->next->next = p2->next;     
p2->next = p1->next;   
p1->next = p2;     
p = p1->next->next;   
}

}
p1 = *head;              
*head = p1->next;    //使头指针指向原来节点位置
free (p1); //释放新建的节点
p1 = NULL;

Many(*head);
}


void Many(struct Student *head) //打印所有学生信息
{
struct Student *human;
int total = 0; //存储已录入信息的人数

human = head;



printf("全部学生信息如下所示:\n");

while (human!=NULL)
{


PrintfInformation(human);

human = human->next;

total++;
}

printf("学生人数%d人!\n\n",total);
}


void Change(struct Student **head) //修改学生信息
{
struct Student *human;
struct Student *hum; //要修改学生的学号的存储位置

hum = (struct Student *)malloc(sizeof(struct Student));
human = *head;

printf("请输入要修改学生的学号:");
scanf("%s",hum->m_strNumber);

while (human!=NULL) //判断该学生信息是否录入
{
if (strcmp(human->m_strNumber,hum->m_strNumber)==0) //查找该学生信息
{
system("cls");

printf("以下操作将对学生信息进行修改:\n");

ChangeHuman(human);

printf("该同学信息已修改成功!\n");

return;
}

human = human->next;
}

system("cls");
printf("该学生信息不存在,请重新查找\n");
}


void ChangeHuman(struct Student *human) //对修改学生信息的菜单处理
{
ChangeMenu();

int input; //修改学生信息操作按钮存储位置

printf("请输入选项:");
scanf("%d",&input);

switch(input)
{
case 1:
printf("请输入学生姓名:");
scanf("%s",human->m_strName);
break;
case 2:
printf("请输入学生性别:");
scanf("%s",human->m_strSex);
break;
case 3:
printf("请输入学生学号:");
scanf("%s",human->m_strNumber);
break;
case 4:
printf("请输入学生英语成绩:");
scanf("%lf",&human->m_fEnglish);
break;
case 5:
printf("请输入学生数学成绩:");
scanf("%lf",&human->m_fMath);
break;
case 6:
printf("请输入学生计算机成绩:");
scanf("%lf",&human->m_fComputer);
break;
}
}


void ChangeMenu() //修改学生信息菜单
{
printf("修改学生姓名----------1\n");
printf("修改学生性别----------2\n");
printf("修改学生学号----------3\n");
printf("修改学生英语成绩------4\n");
printf("修改学生数学成绩------5\n");
printf("修改学生计算机成绩----6\n");
}


void Delete(struct Student **head) //删除目标学生身份
{
struct Student *human;
struct Student *hum; //要删除的学生的学号存储位置
struct Student *temp;

temp = NULL;
human = *head;
hum = (struct Student *)malloc(sizeof(struct Student));

printf("请输入要删除的学生学号:");
scanf("%s",hum->m_strNumber);

if(Compelete(*head,hum)==0) //判断该学生信息是否存在
{
for (; strcmp(human->m_strNumber,hum->m_strNumber)!=0; human=human->next)
{
temp=human;
}

if (temp==NULL)
{
*head=human->next;
}
else 
{
temp->next=human->next;
}

free(human);
temp=NULL;

system("cls");
printf("您已成功删除该学生信息!\n");
}
else 
{
system("cls");
printf("不存在该学生,请先进行录入\n");
}
}


void Statistic(struct Student *head )  //统计不符合要求学生信息
{
struct Student *human;
human = head;
int a = 0; //不符合要求的学生人数的计数器

system("cls");
printf("以下是有两科成绩不及格的同学名单:\n");

for (; human!=NULL; human=human->next)
{
if((human->m_fEnglish>0 &&human->m_fMath>0)||(human->m_fEnglish>0&&human->m_fComputer>0)||(human->m_fComputer>0&&human->m_fMath>0))
{
if ((human->m_fEnglish<60 &&human->m_fMath<60)||(human->m_fEnglish<60&&human->m_fComputer<60)||(human->m_fComputer<60&&human->m_fMath>0))
{
PrintfInformation(human);
a++;

}
}
}
printf("共有%d人不合格",a);
}


void ReadData(struct Student **head) //打开文件,读取信息
{
FILE *fp;
char x;
struct Student *human;
struct Student *temp;
char y; //中间变量
char z;
char w;

char ads[45];

if ((fp=fopen("D:\\1.txt","r"))==NULL)
{
printf("打开文件失败,请建立文件");
}

fseek(fp,81L,SEEK_SET); //将与学生信息无关的文字略掉

x = fgetc(fp);

if (x==EOF) //判断文件是否存储学生信息
{
return ;
}
else
{
fseek(fp,81L,SEEK_SET);      //重新将光标定位到无关文字之后

while (!feof(fp)) //判断文件是否读取结束
{
human = (struct Student *)malloc(sizeof(struct Student));  //建立链表,将信息存储进链表
if (human == NULL)
{
printf("内存分配错误");
exit(1);
}

if (*head == NULL)
{
*head = human;
human->next = NULL;
}
else 
{
temp = *head;

while (temp->next!=NULL)
{
temp = temp->next;
}

temp->next = human;
human->next = NULL;
}

fscanf(fp,"%s", human->m_strName); //读取学生信息
fscanf(fp,"%s",human->m_strSex);
fscanf(fp,"%s",human->m_strNumber);
fscanf(fp,"%lf",&human->m_fEnglish);
fscanf(fp,"%lf",&human->m_fMath);
fscanf(fp,"%lf",&human->m_fComputer);

}
}

fclose(fp);
}


void WriteData (struct Student *head) //保存学生信息,关闭文件
{
FILE *fp;
struct Student *human;
struct Student *temp;

human = head;

if ((fp=fopen("D:\\1.txt","w"))==NULL)
{
printf("打开文件失败,请建立文件");
}
fprintf(fp,"若成绩显示为-1,说明该成绩未被录入!\n");
fprintf(fp,"姓名\t性别\t学号\t英语成绩\t数学成绩\t计算机成绩");

while (human!=NULL)
{
fprintf(fp,"\n%s\t%s\t%s\t%lf\t%lf\t%lf",human->m_strName,human->m_strSex, human->m_strNumber,human->m_fEnglish,human->m_fMath,human->m_fComputer);
human = human->next;
}
fclose(fp);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值