c语言学生成绩管理系统(超详细从文件中读取数据)

c语言学生成绩管理系统(超详细从文件中读取数据)历经一个星期的努力打磨出一个较为完整的学生成绩管理系统注意:本文实在文件中直接读取学生的数据而不是手动添加暂时没有增加添加学生的功能后期更新(多添加一个函数的事情)所有源代码在本文的末尾运行环境:windows由于使用了windows的一个库所以在linux下会出错稍微修改一下也是可以运行的效果图先上结果图界面[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来…

大家好,又见面了,我是你们的朋友全栈君。

历经一个星期的努力

打磨出一个较为完整的学生成绩管理系统

注意:本文实在文件中直接读取学生的数据

而不是手动添加

暂时没有增加添加学生的功能

后期更新(多添加一个函数的事情)

所有源代码在本文的末尾

运行环境:windows

由于使用了windows的一个库

所以在linux下会出错

稍微修改一下也是可以运行的

qq交流群:1046260719 进群可答疑以及课程设计报告等

效果图

先上结果图

界面

c语言学生成绩管理系统(超详细从文件中读取数据)

菜单

c语言学生成绩管理系统(超详细从文件中读取数据)

浏览所有信息

呈现出一个成绩表的效果

c语言学生成绩管理系统(超详细从文件中读取数据)

查询每一个人的数据

分两种查询方式:姓名和学号

c语言学生成绩管理系统(超详细从文件中读取数据)

修改学生数据

两种修改方式:姓名和学号

并能完成实时的更新总分和排名

c语言学生成绩管理系统(超详细从文件中读取数据)

删除学生数据

两种修改方式:姓名和学号

并显示删除学生的数据

c语言学生成绩管理系统(超详细从文件中读取数据)

计算各科成绩的等级

总数本来是30人

由于删除了一个人

所以是29

能完成实时的数据更新

c语言学生成绩管理系统(超详细从文件中读取数据)

各科成绩的最高分最低分和总分

c语言学生成绩管理系统(超详细从文件中读取数据)

退出系统

退出时将更新的数据写在一个新的文件当中

c语言学生成绩管理系统(超详细从文件中读取数据)

实现系统

搭建框架

三个文件

  • student.h 头文件
  • function.cpp 函数文件
  • main.cpp 主函数

####主函数实现菜单的选择

  • 浏览学生信息
  • 查询学生信息
  • 修改学生信息
  • 删除学生信息
  • 各科成绩
  • 最高分最低分
#include"student.h"
#define _CRT_SECURE_NO_WARNINGS
int main()
{ 

char answer;
int choice;
struct student *head ;
head = create(); 
sort(head);
printf("\t\t\t学生成绩管理系统\n");
printf("\n\t************STUDENT-SCORE-SYSTEM 5.0***************\n");
printf("\n\t************powered by 信卓11801聂健***************\n");
printf("\n\t\t\t按任意键登录系统\n");
getchar();
system("cls");
do
{ 

printf("欢迎你,管理员!\n");
printf("|---------------------------------------|\n");
printf("|\t请输入选项编号(0-6):\t\t|");
printf("\n|---------------------------------------|\n");
printf("|\t1--浏览学生信息:\t\t|\n");
printf("|\t2--查询学生信息:\t\t|\n");
printf("|\t3--修改学生信息:\t\t|\n");
printf("|\t4--删除学生信息:\t\t|\n");
printf("|\t5--各科成绩:\t\t\t|\n");
printf("|\t6--最高分:\t\t\t|\n");
printf("|\t0--退出系统:\t\t\t|\n");
printf("|---------------------------------------|\n");
printf("请输入选项");
scanf("%d",&choice);
fflush(stdin);
switch(choice)
{ 

case 0:
{ 

printf("********退出系统*********\n");
filein(head);//将修改后的成绩保存在data11.txt中
printf("修改的数据已经保存在data11.txt中\n");
printf("欢迎下次使用\n");
exit(0);
break;
}
case 1:
{ 

system("cls");
printf("*************学生成绩一览表********************\n");
printf("学号\t姓名\t课程1\t课程2\t课程3\t总分\t排名\n");
print(head); //打印所有人的信息
printf("\n按任意键继续回到菜单\n");
getch();
system("cls");
break;
}
case 2:
{ 

while(1)
{ 

printf("请选择查询方式\n");
printf("1.姓名\n2.学号\n");
scanf("%s",&answer);
if( answer == '1' )
{ 

locatename(head);//查询信息
}
if(answer == '2' )
{ 

locatenum(head);
}
if(answer != '1' && answer!= '2')
{ 

printf("输入错误\n");
}
printf("1.按任意键回车后继续查询\n0.退出\n");
scanf("%s",&answer);
fflush(stdin);
if(answer == '0' )
{ 

break;
}
}
printf("\n按任意键回到菜单");
getch();
system("cls");
break;
}
case 3:
{ 

while(1)
{ 

printf("请选择修改成绩的方式\n");
printf("1.姓名\n2.学号\n");
scanf("%s",&answer);
if(answer == '1')
{ 

changename(head);
sort(head); //修改成绩后重新排序
}
if(answer == '2')
{ 

changenum(head);
sort(head); //修改成绩后重新排序
}
if(answer != '1' && answer!= '2')
{ 

printf("输入错误\n");
}
printf("是否继续\n");
printf("1.按任意键回车后继续修改\n0.退出\n");
scanf("%s",&answer);
if(answer=='0')
{ 

break;
}
}
printf("\n按任意键回到菜单\n");
getch();
system("cls");
break;
}
case 4:
{ 

while(1)
{ 

printf("请选择删除学生的方式\n");
printf("1.姓名\n2.学号\n");
scanf("%s",&answer);
if(answer=='1')
{ 

head= delname(head); //删除头时头要换
sort(head); //删除学生后重新排序
}
if(answer=='2')
{ 

head= delnum(head); //删除头时头要换
sort(head); //删除学生后重新排序
}
if(answer != '1' && answer!= '2')
{ 

printf("输入错误\n");
}
printf("是否继续\n");
printf("1.继续删除\n0.退出\n");
scanf("%s",&answer);
if(answer=='0')
{ 

break;
}
}
printf("\n按任意键继续执行你想要的操作");
getch();
system("cls");
break;
}
case 5:
{ 

ABCD(head);//计算人数
printf("\n按任意键继续执行你想要的操作");
getch();
system("cls");
break;
}
case 6:
{ 

max(head);
printf("\n按任意键继续执行你想要的操作");
getch();
system("cls");
break;
}
default:
{ 

printf("********没有这个选项*********\n按任意键重新输入\n");
getch();
break;
}
} 
}while(1);                           
return 0;
}

在上述的case中加入函数即可完成整个系统

书写各个函数

首先创建一个链表

struct student * create()

在创建链表这个函数返回一个head

在主函数的开头为head开辟一个空间

并使

head = create()

那么在其他函数中调用这个head

就可以访问到这个链表中的所有元素

值得注意的是在删除元素后,因为可能会把头给删掉

所以我们同样要返回头

在其他函数中没有这个要求

使用void无返回值即可

当然也是可以的

//返回head
struct student * delname(struct student *head)
//通过姓名删除学生
//返回head
struct student * delnum(struct student *head)
//通过学号删除学生
void locatename(struct student *head)
//通过姓名去查询数据
//调用这个头指针
//即可遍历这个链表中的所有数据
void locatenum(struct student *head)
//通过学号去查询数据
//调用这个头指针
//即可遍历这个链表中的所有数据
void changename(struct student *head)
//通过姓名去改变数据
//调用这个指针
//即可遍历这个链表中的所有数据
void changenum(struct student *head)
//通过学号去改变数据
//调用这个指针
//即可遍历这个链表中的所有数据
void sort(struct student *head)
//排名
//为什么要单独写一个函数
//老师在检查我的课设的时候我是这样回答的:因为删除学生或者修改学生数据后排名会大声变化,
//所以写成一个函数,以实现每次的实时更新数据
void print(struct student *head)
//打印所有的信息
//实现菜单1的功能
void ABCD(struct student *head)
//统计ABCD等级
//并将此结果写进一个新的文件中设为abcd.txt
void max(struct student *head)
//实现最高分以及最低分以及对应的姓名
//并将此结果写进一个文件当中设为max.txt
//老师在检查课设的时候现场让我添加的一个功能,所以写的有点仓促,并且用了很简单粗暴的方法
void fulein(struct student *head)
//将更新后的数据写进文件中
//将这个函数放在退出系统的那一个菜单
//另外其他两个文件必须要进入那两个菜单中才能实现写进文件中
//当然也可以放在退出系统的那一个菜单中,此时需要定义全局变量

实现各个函数的功能

由于每个函数中都传入了一个参数head

那么都可以访问到链表中的所有数据

这样的话就比较简单了

从一个比较难的系统到实现每个小的功能

所以我建议在做这样的系统的时候

首先要搭好框架

再逐步实现每个模块的功能

这样就变得很简单了

创建链表
 struct student
{ 

char name[20];
float s1;
float s2;
float s3;
float sum;
int rank;
struct student *next;
};
//在头文件中定义
struct student * create()          //建立基础的学生信息库 从文件中将学生信息读取出来
{ 

char title[100];
FILE *fp;
struct student *head, *p , *q;
p = q = (struct student *)malloc(LEN);
if( ( fp = fopen("data00.txt","r") ) == NULL )
{ 

printf( "can't open file\n" );
exit(1);
}
fgets( title, 100, fp );
head = p;
fscanf( fp , "%ld%s%f%f%f\n",&q->num, p->name, &p->s1,&p->s2,&p->s3 );
p->sum = p->s1 + p->s2 + p->s3;
while(!feof(fp))
{ 

q = (struct student *)malloc(LEN);
fscanf( fp,"%ld%s%f%f%f%\n", &q->num,q->name, &q->s1,&q->s2,&q->s3 );
q->sum = q->s1 + q->s2 + q->s3;
p->next = q;
p = q;
}
p->next = NULL;
fclose(fp);
return head;
}

解释:
由于在第一行数据中是字符串

所以使用fgets读取第一行数据

//动态创建链表的过程
struct student *p,*q,*head;
p = q = (struct student *)malloc(sizeof(struct student))//开辟空间
head = p
while(p!=NULL)
{ 

q = (struct student *)malloc(sizeof(struct student));
p->next = q;
p = q;
}
p->next = NULL;
return head;
//在while中将数据域加入即可

由于上述实在文件中读取数据

所以形式上有不同的地方

但是本质是相同的

查询信息
struct student *p,*q;
p = head;
q = p->next;
if(p匹配即头匹配)
{ 

打印p的数据域
}
else
{ 

while(q && 不匹配)
{ 

q = q->next;
}
if(q匹配)
{
打印q的数据域
}
else
{ 

NONE
}
}
删除学生
struct student  *p , *q;
p = head;
while( p不匹配 && p->next!=NULL)
{ 

q = p;
p = p->next;
}//一旦匹配,跳出while
if(匹配)
{ 

if( p == head ) //如果是头匹配
{ 

head = p->next;//换头,此过程就把头也删了
}
else
{ 

q->next = p->next;
}
}
if(不匹配)
{ 

NONE
}
return head;//当删除了头时,把新的头返回
修改学生信息
struct student *p ,*q;
p = head;
while(匹配&&p->next!=NULL)
{ 

q = p;
p = p->next;
}
if(匹配)
{ 

修改数据
计算总分
调用函数排名
}
排名
struct student *p , *q ;
p = head;
while( p ) //擂台法进行排序
{ 

p->sum = p->s1 + p->s2 + p->s3;
p->rank = 1;
q = head;
while(q!=p)
{ 

if((q->sum) > (p->sum))
{ 

p->rank +=1;
}
else if((q->sum)< (p->sum))
{ 

q->rank +=1;
}
q=q->next;
}
p = p->next;
}
输出学生信息
struct student *p;
p = head;
while(p)
{ 

print
p = p->next;
}
计算最高分最低分
struct student *p,q,*summax,summin;
p = head;
q = head;
summax = p;
summin = q;
while(p!=NULL)
{ 

if(p->sum > summax->sum)
{ 

summax = p;
}
p = p->next;
}
while(q!=NULL)
{ 

if(q->sum > summin->sum)
{ 

summin = q;
}
q = q->next;
}
printf("%f",summax->sum);
printf("%f",summin->sum);
写进文件
FILE *fp;
if((fp=fopen("result.txt","w"))==NULL)//打开文件 
{ 

printf("can't open.\n");
exit(-1);
}
fprintf;
fclose(fp);

以上就是实现的所有过程

找到了头就找到了所有的数据

源码下载

c语言学生成绩管理系统(超详细从文件中读取数据)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151603.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 常见函数的定义域_函数定义域的求解

    常见函数的定义域_函数定义域的求解——————————————————————————————————————————————————————————————————…

    2022年10月26日
  • JAVA队列( Queue ) 详解[通俗易懂]

    JAVA队列( Queue ) 详解[通俗易懂]什么是队列?队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删除;比如我们常用的LinkedList集合,它实现了Queue接口,因此,我们可以理解为LinkedList就是一个队列;java队列特性队列主要分为阻塞和非阻塞,有界和无界、单向链表和双向链表之分;阻塞和非阻塞阻塞队列入列(删除元素)时,如果元素数量超过队列总数…

  • clion永久激活码2022 Eval【2021.10最新】

    (clion永久激活码2022 Eval)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

  • CyclicBarrier和CountDownLatch区别

    CyclicBarrier和CountDownLatch区别这两天写多线程时,用到了CyclicBarrier,下意识的认为CyclicBarrier和CountDownLatch作用很像,就翻阅资料查了一下,说一下他们的区别吧CyclicBarrier和CountDownLatch都位于java.util.concurrent这个包下CountDownLatchCyclicBarrier

  • 文本分类算法比较_文本匹配算法

    文本分类算法比较_文本匹配算法本文对常用文本分类算法进行了比较,第一部分包括Rocchio算法,boosting,bagging,,逻辑回归,朴素贝叶斯分类器,k最近邻和支持向量机。另外还包括决策树、条件随机场、随机森林和深度学习算法。第二部分将文本分类技术与标准进行了比较:体系结构、作者、模型、新颖性、特征提取、细节、语料库、验证措施和每种技术的局限性。每个文本分类技术(系统)都包含一个模型,该模型是分类器算法,还需要一个特征提取技术,即将文本或文档数据集转换为数字数据。还列出了用于评估系统的验证措施。文章目录文本分类算法文本分类

    2022年10月28日
  • 数组splice_数组concat方法

    数组splice_数组concat方法有三个方法经常会混淆,但是了解它后你会发现很好区分splice方法是数组特有的方法spite方法是字符串特有的方法slice方法是字符串和数组共同都有的方法这里介绍下数组的常用方法数组的splice方法splice()函数用于从当前数组中移除一部分连续的元素。如有必要,还可以在所移除元素的位置上插入一个或多个新的元素。该函数以数组形式返回从当前数组中被移除的元素。该…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号