使用C语言实现学生信息管理系统

news2024/9/20 7:56:35

前言

在我们实现学生信息管理系统的过程中,我们几乎会使用到C语言最常用最重要的知识,对于刚学习完C语言的同学来说是一次很好的巩固机会,其中还牵扯到数据结果中链表的插入和删除内容。

实现学生信息管理系统

文件的创建与使用

·对于要实现一个大项目而言,我们要把函数进行分装,分装到头文件中,在.c文件中使用

#include"//头文件名"

另外对于定义函数时还可以专门的放在另一个.c文件中,便于维护,在这个小项目中当然不用这样做,不过为了养成好习惯,建议大家这样做。

头文件的使用

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

 创建存储学生信息结构体和节点信息结构体

//学生信息
typedef struct _Student
{
	int stuNum;
	char name[30];
	int source;
}Student;

//节点信息
typedef struct _Node
{
	Student student;
	struct _Node* next;
}Node;

 系统界面的初始化

//初始化界面
void welcome()
{
	printf("**********************************\n");
	printf("*\t学生成绩管理系统\t*\n");
	printf("**********************************\n");
	printf("*\t请选择功能列表\t\t*\n");
	printf("**********************************\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");
}

输入学生信息

//输入学生信息
void inputStudent(Node* head)
{
	Node* fresh = (Node*)malloc(sizeof(Node));
	fresh->next = NULL;
	printf("请输入学生的学号、姓名、成绩:");
	scanf("%d %s %d", &fresh->student.stuNum, fresh->student.name, &fresh->student.source);
	Node* move = head;
	while (move->next != NULL)
	{
		move = move->next;
	}
	//将学生信息插入链表尾部
	move->next = fresh;
	saveStudent(head);//学生信息持久化函数(自定义)
} 

打印学生信息

//打印学生信息
void printStudent(Node* head)
{
	Node* move = head->next;
	while (move != NULL)
	{
		printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.source);
		move = move->next;
	}
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

统计学生人数

//统计学生人数
void countStudent(Node* head)
{
	welcome();

	int count = 0;
	Node* move = head->next;
	while (move != NULL)
	{
		count++;
		move = move->next;
	}
	printf("学生的总人数为%d", count);
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

查找学生信息

void findStudent(Node* head)
{
	welcome();

	int stuNum;
	printf("\n请输入要查找的学生的学号:");
	scanf("%d", &stuNum);
	Node* move = head->next;
	while (move != NULL)
	{
		if (stuNum == move->student.stuNum)
		{
			printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.source);
			return;
		}
		move = move->next;
	}
	printf("未找到学生信息\n");
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

学生信息持久化

//学生信息持久化
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->student, sizeof(Student), 1, file)) != 1)
		{
			printf("写入失败\n");
			return;
		}
		move = move->next;
	}
	fclose(file);
}

读取学生信息

//读取学生信息
void loadStudent(Node* head)
{
	FILE* file = fopen("./stu.info", "r");
	if (!file)
	{
		printf("没有学生文件,跳过读取\n");
		return;
	}
	Node* fresh = (Node*)malloc(sizeof(Node));
	fresh->next = NULL;
	Node* move = head;
	while (fread(&fresh->student, sizeof(Student), 1, file) == 1)
	{
		move->next = fresh;
		move = fresh;
		fresh = (Node*)malloc(sizeof(Node));
		fresh->next = NULL;
	}
	free(fresh);
	fclose(file);
	printf("读取成功\n");
}

修改学生信息

//学生信息修改
void modifyStudent(Node* head)
{
	welcome();

	printf("请输入要修改信息学生的学号:");
	int stuNum;
	scanf("%d", &stuNum);
	Node* move = head->next;
	while (move != NULL)
	{
		if (stuNum == move->student.stuNum)
		{
			printf("请输入学生的姓名、成绩\n");
			scanf("%s %d", move->student.name, &move->student.source);
			saveStudent(head);
			printf("修改成功\n");
			return;
		}
		move = move->next;
		//暂停程序
		system("pause");
//清空控制台
		system("cls");
	}
	printf("未找到学生信息\n");
}

删除学生信息

//删除学生信息
void deleteStudent(Node* head)
{
	welcome();

	int stuNum;

	printf("请输入要删除学生信息的学号");
	scanf("%d", &stuNum);
	
	Node* move = head;
	while (move->next != NULL)
	{
		if (move->student.stuNum == stuNum)
		{
			Node* tmp = move->next;//把要删除的数据的保存的节点存放在一个临时节点中,防止前后节点丢失
			move->next = move->next->next;
			free(tmp);
			tmp = NULL;
			saveStudent(head);
			printf("删除成功\n");
			return;
		}
		move = move->next;
	}
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

链表的删除操作

由于没学到数据结构,这个只是我浅薄的认识。

对学生成绩进行排序

//对学生成绩排序
void sortStudent(Node* head)
{
	welcome();

	Node* move = NULL;
	Node* save = NULL;
	for (Node* turn = head->next; turn->next != NULL; turn = turn->next)
	{
		for (Node* move = head->next; move->next != save; move = move->next)
		{
			if (move->student.source > move->next->student.source)
			{
				Student temp = move->student;
				move->student = move->next->student;
				move->next->student = temp;
			}
		}
		save = move;//下一趟排序不用再次比较已经排序好的最大值

	}
	printStudent(head);
	//暂停程序
	system("pause");
//清空控制台
	system("cls");
}

冒泡排序

冒泡排序是在一趟一趟的过程中对相邻元素比较大小进行排序,例如我们进行升序排序,在每一趟的过程中,会把这一趟的最大元素排到最前面,进而进行下一趟排序,周而复始知道最后一趟的相邻元素大小符合升序排列。

在其中排序的过程中,由于在每一趟中我们会把最大数排列在随后,所以在以后的每一次排序中都不必要对上一趟排序后结果的最大值进行比较,例如:

对于这个算法的实现请看下面:

退出系统以及在main函数中调用这些函数:

int main()
{
	Node* head = (Node*)malloc(sizeof(Node));
	head->next = NULL;
	loadStudent(head);
	welcome();

	while(1)
	{

		char c = _getch();
		switch (c)
		{
			case '1': inputStudent(head);
			break;
		case '2':printStudent(head);
			break;
		case '3':countStudent(head);
			break;
		case '4':findStudent(head);
			break;
		case '5':modifyStudent(head);
			break;
		case '6':deleteStudent(head);
			break;
		case '7':sortStudent(head);
			break;
		case '8':printf("\n欢迎下次使用,bye-");
			     exit(0);
			break;
		default:printf("请重新输入\n");
			break;
		}
	}
	
	return 0;
}


退出系统

总结

对于前面的函数实现而言,大多数代码的思路是相同的,对于学生信息的删除和成绩排序需要我们重点理解,愿与诸君共勉!

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

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

相关文章

【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记

1. 引言 因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9)&#xff0c;本人之前没有接触过这款单片机&#xff0c;为了维护老产品不得不重新研究研究这款单片机。 10位ADC LCD的增强型8051微控制器 SH79F9202是一种高速高效率8051可兼容单片机。在同样振…

5G工厂长啥样

5G工厂是一种新型的工业互联网基础设施&#xff0c;利用5G为代表的新一代信息通信技术集成&#xff0c;打造新型工业互联网基础设施。在5G工厂中&#xff0c;自动化和智能化设备广泛使用&#xff0c;高度互联的工厂网络得以实现&#xff0c;远程监控和管理成为可能&#xff0c;…

鸿蒙应用模型:【Stage模型开发】概述

Stage模型开发概述 基本概念 下图展示了Stage模型中的基本概念。 图1 Stage模型概念图 [AbilityStage] 每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例&#xff0c;当HAP中的代码首次被加载到进程中的时候&#xff0c;系统会先创建AbilityStage实例…

微信网页版登录插件v1.1.1

说到如今的微信客户端&#xff0c;大家肯定会有很多提不完的意见或者建议。比如这几年体积越来越大&#xff0c;如果使用频率比较高&#xff0c;那占用空间就更离谱了。系统迷见过很多人电脑C盘空间爆满&#xff0c;都是由于微信PC版造成的。 而且&#xff0c;它还加了很多乱七…

【第8章】SpringBoot之单元测试

文章目录 前言一、准备1. 引入库2. 目录结构 二、测试代码1. SpringBoot3ApplicationTests2.测试结果 总结 前言 单元测试是SpringBoot项目的一大利器&#xff0c;在SpringBoot我们可以很轻松地测试我们的接口。 一、准备 1. 引入库 <dependency><groupId>org.s…

【JS基础知识07】函数

一&#xff1a;函数是什么以及函数作用 1 函数是什么 函数是经过封装、调用后&#xff0c;能够完成特定任务的代码块 2 函数的作用 仅需“函数名(实参)”就可以调用函数&#xff0c;起到精简代码&#xff0c;提高开发效率的作用 二&#xff1a;函数使用 1 语法规则&#…

Android 控件保持宽高比得几种方式

文章目录 Android 控件保持宽高比得几种方式adjustViewBounds百分比布局ConstraintLayout自定义View Android 控件保持宽高比得几种方式 adjustViewBounds 仅适用于 ImageView&#xff0c;保持横竖比。 <ImageViewandroid:layout_width"match_parent"android:l…

【使用ChatGPT构建应用程序】应用程序开发概述:1. 管理秘钥、2. 数据安全、3. 与应用程序解耦、4. 注意提示语的注入攻击

文章目录 一. 首先注意的两个方面1. 管理API密钥1.1. 用户提供API密钥1.2. 你自己提供API密钥 2. 数据安全和数据隐私 二. 软件架构设计原则&#xff1a;与应用程序解耦三. 注意LLM提示语的注入攻击1. 分析输入和输出2. 监控和审计3. 其他要注意的注入情况 在了解了ChatGPT的文…

SheetJS V0.17.5 导入 Excel 异常修复 Invalid HTML:could not find<table>

导入 Excel 提示错误&#xff1a;Invalid HTML:could not find<table> 检查源代码 发现 table 属性有回车符 Overview: https://docs.sheetjs.com/docs/ Source: https://git.sheetjs.com/sheetjs/sheetjs/issues The public-facing websites of SheetJS: sheetjs.com…

Linux静态库、共享动态库介绍、制作及使用

参考学习&#xff1a;Linux下的各种文件 、动态库基本原理和使用方法&#xff0c;-fPIC选项的来龙去脉 、Linux静态库和动态库分析 文章写作参考&#xff1a;Linux共享库、静态库、动态库详解 - sunsky303 - 博客园 (cnblogs.com) 一.Linux共享库、静态库、动态库详解 使用G…

2021CSP-J普及组复赛-第一题:分糖果

2021CSP-J普及组复赛 第一题&#xff1a; 题目&#xff1a; 输入&#xff1a; 7 16 23输出&#xff1a; 6思路&#xff1a; 这是一个简单的思考题&#xff0c;没有用到重要的算法 ①简单的思路即暴力方法就是利用for循环从L 到 R 遍历求出其中最大的奖励值&#xff0c;由于R…

全程曝光 计算机领域顶会投稿后会经历哪些关键环节?

会议之眼 快讯 亲爱的计算机领域大牛们&#xff0c;当你挥洒汗水&#xff0c;精心打磨一篇科研论文&#xff0c;终于怀着激动的心情投稿至顶会——&#xff08;如&#xff08;ACM MM 、ACL、AAAI&#xff09;时&#xff0c;你是否想知道接下来这篇论文会经历怎样的旅程&#x…

数据结构(1):线性表

1 线性表的顺序实现 创建的新项目是cpp类型哦&#xff01; 1.1 初始化 1.1.1 静态分配 #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #define MaxSize 10 //定义顺序表的长度 typedef struct {int data[MaxSize];//用静态的数组存放元素&#xff01;int lengt…

【错题集-编程题】小红取数(动态规划 - 01 背包 + 同余)

牛客对应题目链接&#xff1a;小红取数_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 这道题是不能用空间优化的。 同余原理 a % k x 和 b % k y <> (ab) % k 0 <> (xy) % k 0 状态表示 dp[i][j]&#xff1a;表示从前 i 个数中挑选&#xff0c;总和 %k 等于 j…

一篇文章搞懂二叉树

文章目录 DP 树叶的度树的度节点的层次节点的祖先节点的子孙双亲节点或父节点 树的表示孩子兄弟表示法双亲表示法树和非树树的应用 二叉树满二叉树完全二叉树推论二叉树的存储以数组的方式以链表的方式堆(Heap)堆的分类大根堆和小根堆的作用 二叉树的遍历DFS和BFS DP 动态规划…

NVR对接三方相机预览黑屏问题案例

一、 问题现象 【问题现象】NVR接入三方相机,通道状态显示在线,但本地、web预览显示黑屏。更换H.264&#xff0c;H.265均预览黑屏&#xff0c;且NVR侧的萤石云手机APP预览报错260025。 【现场拓扑】现场拓扑如下 &#xff08;1&#xff09; IPC使用onvif协议添加至NVR&#xff…

Facebook的魅力:数字时代的社交热点

在当今数字化时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的巨头&#xff0c;一直以其独特的魅力吸引着全球数十亿用户。本文将深入探讨Facebook的魅力所在&#xff0c;以及它在数字时代的社交热点。 1. 社交网络的霸主&…

如何做好投入式水位计的安装与维护

投入式水位计是一种广泛应用于各种环境和水位监测场景的精确测量设备。为了确保其长期稳定运行和测量准确性&#xff0c;正确的安装和维护至关重要。本文将详细介绍投入式水位计的安装步骤和注意事项&#xff0c;以及维护过程中的关键要点。 一、投入式水位计的安装 准备工作&a…

JAVA类与方法·易错题分析

分析一下作业中关于类与方法写错或者易错的题。 N o . 1 No.1 No.1 下面程序的执行结果是______。 public class Test7 {public static void main(String[] args){new B().display();} } class A{public void draw() {System.out.print("Draw A.");}public void di…

基于STM32单片机老人体温心率血氧跌倒定位短信报警

一.硬件及设计功能 以STM32F103C8T6为中央处理器&#xff0c;GPS模块用采集数据&#xff0c;将数据发送给单片机后&#xff0c;单片机根据定位计算公式得出当前位置的经纬度信息和时间信息。经过LCD显示器处理后得出和时间信息SIM800模块发送短信到设定的手机号上&#xff0c;将…