学生管理系统

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 0. 准备
    • 0-0 头文件
    • 0-1 封装学生和结点数据
    • 0-2 创建头结点
    • 0-3 系统功能提示
    • 0-4 根据用户输入选择功能
  • 1. 录入学生信息
    • 1-0 实现循环录入
    • 1-1 程序暂停和清空控制台
  • 2. 打印学生信息
  • 3. 统计学生人数
  • 4. 查找学生信息
  • 4-0. 学生信息持久化
  • 5. 修改学生信息
  • 6. 删除学生信息
  • 7. 按成绩排序
  • 8. 退出系统
  • 总结


前言

本程序使用纯C制作一个学籍管理系统。利用单链表实现学生管理系统,具体功能包括录入学生信息、打印学生信息、统计学生人数、查找学生信息、修改学生信息、删除学生信息、按成绩排序
同时将学生信息保存至文件中,当再次启动程序时,自动读取学生数据。


0. 准备

0-0 头文件

创建StudentManager.h ,加入以下代码

// 标准输入输出
#include <stdio.h>
// _getch:不需要回车,直接获取输入的字符,需要包含conio.h头文件#include <conio.h>
// 动态申请内存
#include <stdlib.h>

0-1 封装学生和结点数据

定义学生结构体,用于保存学生的学号、姓名、成绩信息,并使用typedef给 struct _Student 类型起别名为Student ,方便使用。

typedef struct _Student
{int stuNum; //学号char name[20];//姓名int score; //成绩
}Student;

定义结点结构体,用于保存链表中的结点数据,结点需要保存学生信息及下一个结点的地址,并使用
typedef给 struct _Node 类型起别名为Node ,方便使用。

typedef struct _Node
{Student stu; //学生struct _Node* next; //指向下一个结点的指针
}Node;

0-2 创建头结点

创建StudentManager.c ,加入main函数,并创建链表的头结点,定义head头指针指向头结点

//导入头文件
#include "StudentManager.h"
int main() {//创建头结点Node* head = malloc(sizeof(Node)); head->next = NULL;return 0;
}

0-3 系统功能提示

定义welcome函数,用于提示用户系统功能

void welcome() {printf("*********************************\n"); printf("*\t学生成绩管理系统\t*\n");  printf("*\t请选择功能列表\t\t*\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*\n");printf("*\t6.删除学生信息\t\t*\n");printf("*\t7.按成绩排序\t\t*\n"); printf("*\t8.退出系统\t\t*\n");printf("*********************************\n");
}

在头文件中声明函数,并在main函数中调用,后面定义的其他函数,也应该先在头文件中声明,再调 用:
StudentManager.h

//欢迎信息
void welcome();

main函数

//创建头结点
Node* head = malloc(sizeof(Node)); head->next = NULL;welcome();

0-4 根据用户输入选择功能

通过_getch() 函数获取用户输入的单个字符,此函数不需要回车,并通过switch进行判断

welcome();
char c = _getch(); switch (c)
{case '1'://录入学生信息break; case '2'://打印学生信息break;case '3'://统计学生人数break; case '4'://查找学生信息break; case '5'://修改学生信息break;case '6'://删除学生信息break; case '7'://按成绩排序break; case '8'://退出系统break;default:break;
}

1. 录入学生信息

定义inputStudent 函数,实现新增学生信息的功能,在main函数中调用。

void inputStudent(Node* head) {//定义指针指向头结点,用于遍历链表Node* move = head;while (move->next != NULL) { move = move->next;}//创建结点Node* fresh = malloc(sizeof(Node)); fresh->next = NULL;//输入用户信息printf("请输入学生的学号、姓名、成绩: ");scanf("%d%s%d", &fresh->stu.stuNum, fresh->stu.name, &fresh->stu.score);//将新创建的结点,添加到链表的尾部move->next = fresh;
}

在main函数中调用

...case '1': //录入学生信息inputStudent(head); break;
...

1-0 实现循环录入

添加循环,将welcome 函数及switch判断都加入到循环体,保持程序一直运行,实现循环录入学生信息功能

int main() {//创建头结点Node* head = malloc(sizeof(Node));head->next = NULL;while (1) {welcome();/*等待从键盘接收一个字符, 输入字符后,回车才能录入,注意:回车符号会被存储至缓存区,下次循环导致获取到回车//char c = getchar();//getchar(); 吸收回车getch:不需要回车,直接获取输入的字符,需要包含conio.h头文件,2022之前的版本需要使用_getch()*/char c = _getch();switch (c) {case '1': //录入学生信息inputStudent(head);break;case '2': //打印学生信息break;case '3': //统计学生人数break;case '4': //查找学生信息break;case '5': //修改学生信息break;case '6': //删除学生信息break;case '7': //按成绩排序break;case '8': //退出系统break;default:break;}}return 0;
}

注意,如果使用的是 getchar 函数或 scanf 函数,会存在缓冲区的问题,每次输入数据后,回车都会被
保存到缓冲区,导致下次出现问题,需要再使用一次getchar吸收回车。
_getch 函数不需要回车就可以直接读取到数据,不存在此问题。

1-1 程序暂停和清空控制台

每次录入学生信息后,进入到下一次循环,会重新打印欢迎信息,可以先使程序暂停,等待用户下一步指示

system("pause");//按下任意键后,会继续执行程序

当用户按下任意键后,可以先清空控制台,防止重复出现欢迎信息

system("cls");

两者合用,加入到 inputStudent 函数中

void inputStudent(Node* head) {//定义指针指向头结点,用于遍历链表Node* move = head;......system("pause");system("cls");
}

2. 打印学生信息

定义 printStudent 函数,实现打印所有学生信息的功能

void printStudent(Node* head) {Node* move = head->next;while (move != NULL) {printf("学号:%d 姓名:%s 成绩:%d\n",move->stu.stuNum,move->stu.name,move->stu.score);move = move->next;}system("pause");system("cls");
}

在main函数中调用

...case '2': //打印学生信息printStudent(head);break;
...

3. 统计学生人数

定义 countStudent 函数,统计学生总人数

void countStudent(Node* head) {int count = 0;Node* move = head->next;while (move != NULL) {count++;move = move->next;}printf("学生总人数为:%d\n",count);system("pause");//清屏system("cls");
}

在main函数中调用

	case '3': //统计学生人数countStudent(head);break;

4. 查找学生信息

定义 findStudent 函数,用于根据学号查找学生信息

void findStudent(Node* head) {int stuNum;printf("请输入要查找的学生的学号: ");scanf("%d", &stuNum);Node* move = head->next;while (move != NULL) {if (move->stu.stuNum = stuNum) {printf("学号:%d 姓名:%s 成绩:%d\n", move->stu.stuNum, move->stu.name,move->stu.score);system("pause");system("cls");return;}move = move->next;}printf("未查找到学生信息\n");system("pause");system("cls");
}

在main函数中调用

case '4': //查找学生信息findStudent(head);

4-0. 学生信息持久化

定义 saveStudent 函数,将链表数据保存至文件中

void saveStudent(Node* head) {//打开文件FILE* file = fopen("./stu.info", "w");if (file == NULL) {printf("打开文件失败\n");return;}Node* move = head->next;while (move != NULL) {//将结构体写入文件if (fwrite(&move->stu, sizeof(Student), 1, file) != 1) {printf("保存%s出现错误\n", move->stu.name);}move = move->next;}//关闭文件fclose(file);
}

在 inputStudent 函数中调用 saveStudent ,实现信息的保存

void inputStudent(Node* head) {//定义指针指向头结点,用于遍历链表Node* move = head;...//将学生信息保存至文件saveStudent(head);system("pause");system("cls");
}

定义 loadStudent 函数实现学生信息的读取

void loadStudent(Node* head) {//打开文件FILE* file = fopen("./stu.info", "r");if (!file) {printf("未找到学生文件,跳过读取\n");return;}//创建一个结点Node* fresh = malloc(sizeof(Node));fresh->next = NULL;Node* move = head;while (fread(&fresh->stu, sizeof(Student), 1, file) == 1) {move->next = fresh;move = fresh;fresh = malloc(sizeof(Node));fresh->next = NULL;}free(fresh); //最后多定义一个fresh,要将它释放掉//关闭文件fclose(file);printf("读取成功\n");
}

在main函数中调用 loadStudent ,每次程序启动时,先读取之前存储的学生信息

int main() {//创建头结点Node* head = malloc(sizeof(Node));head->next = NULL;//读取学生信息loadStudent(head);
}

5. 修改学生信息

定义 modifyStudent 函数,用于根据学生学号修改学生信息

void modifyStudent(Node* head) {printf("请输入需要修改的学生学号 ");int stuNum = 0;scanf("%d", &stuNum);Node* move = head;while (move != NULL) {if (move->stu.stuNum == stuNum) {printf("请输入学生姓名,成绩\n");scanf("%s%d",move->stu.name,&move->stu.score);printf("修改学生信息成功\n");//不再循环break;}move = move->next;}//如果循环完毕,也没找到学生if (move == NULL) {printf("未找到学生信息\n");}//同步到文件saveStudent(head);system("pause");system("cls");
}

在main函数中调用

case '5': //修改学生信息modifyStudent(head);break;

6. 删除学生信息

定义 deleteStudent 函数,用于根据学号删除学生

void deleteStudent(Node* head) {printf("请输入要删除的学生学号 ");int stuNum = 0;scanf("%d", &stuNum);Node* move = head;while (move->next != NULL) {if (stuNum == move->next->stu.stuNum) {Node* temp = move->next;move->next = move->next->next; //删除结点只需要一句free(temp); //最后记得将删除的动态空间释放掉temp = NULL; //释放后随即指向NULL//同步到文件saveStudent(head);printf("删除学生成功\n");break;}move = move->next;}if (move->next == NULL) {printf("未找到学生信息\n");}system("pause");system("cls");
}

7. 按成绩排序

定义 sortStudent 函数,使用冒泡排序,按成绩从小到大进行排序

void sortStudent(Node* head) {Node* save = NULL;Node* move = NULL;for (Node* turn = head->next; turn->next != NULL; turn = turn->next) {for (move = head->next; move->next != save; move = move->next) {if (move->stu.score > move->next->stu.score) {Student temp = move->stu;move->stu = move->next->stu;move->next->stu = temp;}}save = move;}printStudent(head);
}

在main函数中调用

case '7': //按成绩排序sortStudent(head);

8. 退出系统

	case '8': //退出系统system("cls");printf("Bye Bye!\n");exit(0);

总结

学籍管理系统是一种基于单链表的学生管理系统,通过使用纯C语言实现。该系统具有多项功能,包括录入学生信息、打印学生信息、统计学生人数、查找学生信息、修改学生信息、删除学生信息以及按成绩排序。此外,该系统还具备学生信息持久化的功能,能够将学生数据保存至文件中,以便下次启动程序时自动读取。在录入学生信息功能中,用户可以逐个输入学生的学号、姓名和成绩。打印学生信息功能可以将系统中存储的所有学生信息依次输出。统计学生人数功能可以统计出当前系统中的学生总人数。查找学生信息功能可以根据学号查找学生的详细信息。修改学生信息功能可以根据学号修改学生的姓名和成绩。删除学生信息功能可以根据学号删除学生的信息。按成绩排序功能可以将学生信息按照成绩从小到大进行排序。最后,退出系统功能可以结束程序的运行。通过以上功能,学籍系统可以方便地管理学生的信息,并能够保证数据的持久化安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/98819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【jvm--方法区】

文章目录 1. 栈、堆、方法区的交互关系2. 方法区的内部结构3. 运行时常量池4. 方法区的演进细节5. 方法区的垃圾回收 1. 栈、堆、方法区的交互关系 方法区的基本理解&#xff1a; 方法区&#xff08;Method Area&#xff09;与 Java 堆一样&#xff0c;是各个线程共享的内存区…

4.MySql安装配置(更新版)

MySql安装配置 无论计算机是否有安装其他mysql&#xff0c;都不要卸载。 只要确定大版本是8即可&#xff0c;8.0.33 8.0.34 差别不大即可。 MySql下载安装适合电脑配置属性有关&#xff0c;一次性安装成功当然是非常好的&#xff0c;因为卸载步骤是非常麻烦的 如果第一次安装…

医疗器械标准目录汇编2022版共178页(文中附下载链接!)

为便于更好地应用医疗器械标准&#xff0c;国家药监局医疗器械标准管理中心组织对现行1851项医疗器械国家和行业标准按技术领域&#xff0c;编排形成《医疗器械标准目录汇编&#xff08;2022版&#xff09;》 该目录汇编分为通用技术领域和专业技术领域两大类&#xff0c;通用…

NoSQL Redis

NoSQL Redis 1、数据库1.1关系型数据库1.2非关系型数据库1.3关系型和非关系型区别 2、非关系型数据库应用场景3、存储结构4、redis4.1redis概述4.2Redis 优点4.3Redis为什么这么快&#xff1f; 5、部署redis6、redis基础操作 1、数据库 1.1关系型数据库 关系型数据库是一个结…

互斥锁、条件变量、信号量以及适用场景

文章目录 互斥锁互斥锁实战过程中常用方法 条件变量条件变量实战过程中常用方法 信号量信号量的常用方法 生产者和消费者问题一个粗略版本的生产者消费者代码(如果只使用了互斥锁)一个改进版本的生产者消费者代码(使用了互斥锁和条件变量)一个最终版本的生产者消费者代码(使用了…

options.css 内容优化2 --chatPGT

问&#xff1a; options.css 内容优化,功能列表的li,设置成点击按钮的样式&#xff0c;需要有鼠标经过高亮&#xff0c;选中时按钮背景颜色和未选中时的背景色需要有肉眼可见的色差 gpt: 为了使左侧功能列表的每个 <li> 元素看起来像按钮&#xff0c;并且在鼠标经过时…

机械臂抓取的产业落地进展与思考

工业机械臂是一种能够模拟人类手臂动作的机械装置&#xff0c;具有高精度、高速度和高灵活性的特点。近年来&#xff0c;随着人工智能和机器人技术的快速发展&#xff0c;机械臂在工业生产、物流仓储、医疗护理等领域得到了广泛应用。机械臂抓取技术作为机械臂的核心功能之一&a…

广东省科学技术厅关于2023年度广东省科学技术奖提名工作的通知

粤科函区字〔2023〕1290号 各有关单位&#xff08;专家&#xff09;&#xff1a; 科技奖励制度是党和政府长期坚持的一项重要科技制度&#xff0c;为深入实施创新驱动发展战略&#xff0c;加快建设更高水平的科技创新强省和粤港澳大湾区国际科技创新中心&#xff0c;进一步体现…

tp5访问的时候必须加index.php,TP5配置隐藏入口index.php文件

PS&#xff1a;这里说的入口文件指的是public/index.php,配置文件就在这个目录下 可以去掉URL地址里面的入口文件index.php&#xff0c;但是需要额外配置WEB服务器的重写规则。 以Apache为例&#xff0c;需要在入口文件的同级添加.htaccess文件(官方默认自带了该文件)&#x…

基于Keil a51汇编 —— MPL 宏定义

MPL 宏 Ax51汇编程序支持的宏处理语言&#xff08;MPL&#xff09;是一种字符串替换工具&#xff0c;使您能够编写可修复的代码块&#xff08;宏&#xff09;并将其插入源文本中的一个或多个位置。 宏处理器查看源文件的方式与汇编程序不同。 对于汇编程序来说&#xff0c;源…

UniAD 论文学习

一、解决了什么问题&#xff1f; 当前的自动驾驶方案大致由感知&#xff08;检测、跟踪、建图&#xff09;、预测&#xff08;motion、occupancy&#xff09;和规划三个模块构成。 为了实现各种功能&#xff0c;智驾方案大致包括两种路线。一种是针对每个任务都部署一个模型&a…

Python Parser 因子计算性能简单测试

一直以来&#xff0c;Python 都在量化金融领域扮演着至关重要的角色。得益于 Python 强大的库和工具&#xff0c;用户在处理金融数据、进行数学建模和机器学习时变得更加便捷。但作为一种解释性语言&#xff0c;相对较慢的执行速度也限制了 Python 在一些需要即时响应的场景中的…

读取 yaml 文件

一、引入依赖 <dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.32</version> </dependency> 二、读取yaml内容工作代码 &#xff08;1&#xff09;上传yaml文件 读取yaml文件并校验…

知识图谱系列3:读论文-《中国鸟类领域知识图谱构建与应用研究》-面向知识图谱的智能服务研究(需求、管理、查询、推理)

5.1鸟类领域知识服务需求研究 本部分根据不同人群&#xff0c;对其需求进行了研究。 并总结需求类型如下。 知识型服务需求指用户学习鸟类相关知识&#xff0c;包括知识内容、知识学习等。知识内容 需求为构建鸟类领域知识库作为知识的来源&#xff1b;知识学习需求为用户通过…

gici-open示例数据运行(ground_truth坐标的转换)

1. 坐标系转换说明 涉及的两个坐标转换&#xff1a; nmea_pose_to_pose &#xff1a;激光IMU中心到数据集IMU中心&#xff0c;主要是杆臂误差&#xff0c;转换关系为&#xff1a; //坐标转换的主要步骤(若发现有错误的地方&#xff0c;请评论指出) //定义激光IMU和数据集IMU之…

好看的机制示意图绘制教程汇总

好看的机制示意图绘制教程汇总 蛋白翻译过程示意图&#xff0c;特别是其中的核糖体&#xff0c;需要很多绘制技巧。主要使用椭圆工具绘制两个椭圆&#xff0c;二者组合后使外形接近核糖体。接着通过路径查找器的合并功能&#xff08;并集&#xff09;将两个椭圆合并在一起。使…

使用HHDBCS管理MongoDB

1 连接MongoDB 打开HHDBCS&#xff0c;在数据库类型中选择mongodb&#xff0c;填入相关信息&#xff0c;点击“登陆”即可。 也可以使用SSH通道进行登陆。 2 命令窗口 点击命令窗口&#xff0c;可以对数据库发出指令。 可以根据个人习惯&#xff0c;对命令窗口进行设置…

矩阵的相似性度量的常用方法

矩阵的相似性度量的常用方法 1&#xff0c;欧氏距离 欧式距离是最易于理解的一种距离计算方法&#xff0c;源自欧式空间中两点间的距离公式。 (1)二维平面上的点 a ( x 1 , y 1 ) a(x_1,y_1) a(x1​,y1​)和点 b ( x 2 , y 2 ) b(x_2,y_2) b(x2​,y2​)的欧式距离为 d ( x …

uni-app:引入echarts(使用renderjs)

效果 代码 <template><view click"echarts.onClick" :prop"option" :change:prop"echarts.updateEcharts" id"echarts" class"echarts"></view> </template><script>export default {data()…

旅游网站HTML

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>旅游网</title> </head> <body><!--采用table编辑--> <!--最晚曾table,用于整个页面那布局--><table width&q…