【C语言】手写学生管理系统丨附源码+教程
最近感觉大家好多在忙C语言课设~
我来贡献一下,如果对你有帮助的话谢谢大家的点赞收藏喔!
1. 项目分析
小白的神级项目,99%的程序员,都做过这个项目!
掌握这个项目,就基本掌握 C 语言了!
跳过这个项目,永远是小白!
2. 项目准备
VS 的任意版本(推荐 VS2010/VS2019)
任意版本的 C 语言开发环境、
3. 创建项目
1. 创建空项目。
2. 编写测试代码
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("hello world\n");
system("pause");
return 0;
}
4. 编写功能菜单
初级版
int main(void) {
printf("
学生信息管理系统\n");
printf("1. 输入学生信息\n");
printf("3. 删除学生信息\n");
printf("3. 删除学生信息\n");
printf("4. 修改学生信息\n");
printf("5. 插入学生信息\n");
printf("6. 学生成绩排名\n");
printf("7. 统计学生总数\n");
printf("8. 显示所有信息\n");
printf("0. 退出系统\n");
system("pause");
return 0;
}
表格版
使用表格形式打印。
导入第 3 行工具(Rock 开发,可以进一步完善)
公众号:奇牛编程
回复关键字:管理系统
初始化窗口大小
void init() {
char cmd[128];
sprintf(cmd, "mode con lines=%d cols=%d", WIN_HEIGHT, WIN_WIDTH);
system(cmd);
}
int main(void) {
init();
......
return 0;
}
创建菜单函数 menu
void menu() {
system("cls");
printTableHead(MENU_WIDTH);
printTableMidInfo(MENU_WIDTH, "学生信息管理系统");
printTableMidInfo(MENU_WIDTH, "");
const char* subMenus[] = {
"1. 输入学生信息",
"2. 查找学生信息",
"3. 删除学生信息",
"4. 修改学生信息",
"5. 插入学生信息",
"6. 学生成绩排名",
"7. 统计学生总数",
"8. 显示所有信息",
"0. 退出系统 "
};
int count = sizeof(subMenus) / sizeof(subMenus[0]);
for (int i = 0; i < count; i++) {
printTableMidInfo(MENU_WIDTH, subMenus[i]);
}
printTableMidInfo(MENU_WIDTH, "");
printTableTail(MENU_WIDTH);
printMidInfo("请选择(0-8): ");
}
调用 menu 函数
int main(void) {
init();
menu();
return 0;
}
上色
color -?
void init() {
char cmd[128];
sprintf(cmd, "mode con lines=%d cols=%d", WIN_HEIGHT, WIN_WIDTH);
system(cmd);
system("color 1f"); //system("color f0\n");
}
5. 菜单选择
int main(void) {
init();
menu();
int n;
scanf("%d", &n);
while (1) {
switch (n) {
case 1: input();break;
case 2: search();break;
case 3: del(); break;
case 4: modify(); break;
case 5: insert(); break;
case 6: order(); break;
case 7: total(); break;
case 8: show(); break;
default:break;
}
waitConfirm();
menu();
rewind(stdin); // fflush(stdin),在 VS2015 以上无效
scanf("%d", &n);
}
return 0;
}
添加的各功能接口:
void input() {
system("cls");
printf("输入...\n");
}
void search() {
system("cls");
printf("查询...\n");
}
void del() {
system("cls");
printf("删除...\n");
}
void modify() {
system("cls");
printf("修改...\n");
}
void insert() {
system("cls");
printf("插入...\n");
}
void order() {
system("cls");
printf("排序...\n");
}
void total() {
system("cls");
printf("统计...\n");
}
void show() {
system("cls");
printf("显示...\n");
}
void waitConfirm() {
rewind(stdin); //flush(stdin)在 VS2015 以上无效,使用 rewind,清空缓存
getch();
}
学生信息的表示
struct student {
int num; //学号
char name[16];
int cLang; //C 语言
int algo; //算法
int database; //数据库
int sum;
};
学生信息的存储
在内存中的存储
#define MAX_COUNT 100
struct student stu[MAX_COUNT];
int currentCount = 0;
在文件中的存储
data.txt
初始化学员信息
void init() {
char cmd[128];
sprintf(cmd, "mode con lines=%d cols=%d", WIN_HEIGHT, WIN_WIDTH);
system(cmd);
system("color 1f"); //system("color f0\n");
memset(stu, 0, sizeof(stu));
FILE* fp = fopen("data.txt", "rb");
if (fp == NULL) {
//printf("文件不存在!\n");
currentCount = 0;
return;
}
int i = 0;
while (!feof(fp)) {
int ret = fread(&stu[i], sizeof(struct student), 1, fp);
if (ret == 1) {
i++;
}
}
currentCount = i;
}
输入学生信息
实现输入功能
void input() {
char str[16];
struct student s;
while (1) {
system("cls");
printf("输入学生信息(y/n):");
rewind(stdin); //清空输入缓存区
scanf("%s", str);
if (strcmp(str, "Y") != 0 && strcmp(str, "y") != 0) {
break;
}
s = inputInfo();
if (searchStu(s.num) >= 0) {
printf("学号[%d] 已经存在!\n", s.num);
waitConfirm();
continue;
}
stu[currentCount++] = s;
if (!save()) {
printf("保存失败!\n");
}
else {
printf("保存成功!\n");
}
waitConfirm();
}
printf("\n 结束输入!\n");
}
inputInfo 函数
struct student inputInfo() { //可优化成使用指针参数
struct student s;
rewind(stdin); //清空输入缓存区
printf("学号:");
scanf("%d", &s.num);
printf("姓名:");
scanf("%s", s.name);
printf("C 语言:");
scanf("%d", &s.cLang);
printf("算法:");
scanf("%d", &s.algo);
printf("数据库:");
scanf("%d", &s.database);
s.sum = s.cLang + s.algo + s.database;
return s;
}
searchStu 函数
int searchStu(int snum) {
for (int i = 0; i < currentCount; i++) {
if (stu[i].num == snum) {
return i;
}
}
return -1;
}
save 函数
bool save() {
FILE *fp = fopen("data.txt", "wb");
if (fp == NULL) {
fclose(fp);
return false;
}
for (int i = 0; i < currentCount; i++) {
if (fwrite(&stu[i], sizeof(struct student), 1, fp) != 1) {
fclose(fp);
return false;
}
}
fclose(fp);
return true;
}
显示学生信息
#define RECORDER_PER_PAGE 10
void show() {
system("cls");
if (currentCount == 0) {
printf("还没有学生信息!\n");
return;
}
int pageCount = (currentCount + RECORDER_PER_PAGE - 1) / RECORDER_PER_PAGE;
char buff[64];
for (int i = 0; i < pageCount; i++) {
showPage(i * RECORDER_PER_PAGE, (i + 1) * RECORDER_PER_PAGE - 1);
sprintf(buff, "共%d 页 第[%d]页", pageCount, i + 1);
printMidInfo(buff);
if (i < pageCount - 1) {
waitConfirm();
}
}
}
showPage 函数
// 表头信息
char head[][COL_LEN_MAX] = { "学号", "姓名", "C 语言", "算法", "数据库", "总分" };
void showPage(int startIndex, int endIndex) {
if (endIndex >= currentCount) {
endIndex = currentCount - 1;
}
if (endIndex - startIndex + 1 > RECORDER_PER_PAGE) {
endIndex = startIndex + RECORDER_PER_PAGE - 1;
}
char row[6][COL_LEN_MAX];
system("cls");
printTableHead(TABLE_WIDTH, 6);
printTableRow(TABLE_WIDTH, head, sizeof(head) / sizeof(head[0]));
printTableMidLine(TABLE_WIDTH, 6);
for (int i = startIndex; i <= endIndex; i++) {
sprintf(row[0], "%d", stu[i].num);
sprintf(row[1], "%s", stu[i].name);
sprintf(row[2], "%d", stu[i].cLang);
sprintf(row[3], "%d", stu[i].algo);
sprintf(row[4], "%d", stu[i].database);
sprintf(row[5], "%d", stu[i].sum);
printTableRow(TABLE_WIDTH, row, 6);
if (i < endIndex) {
printTableMidLine(TABLE_WIDTH, 6);
}
else {
printTableTail(TABLE_WIDTH, 6);
}
}
}
查询学生信息
void search() {
int snum = 0;
system("cls");
printf("请输入学号:");
scanf("%d", &snum);
int i = searchStu(snum);
if (i < 0) {
printf("没有找到这名学生!\n");
return;
}
char row[6][COL_LEN_MAX];
char head[][COL_LEN_MAX] = { "学号", "姓名", "C 语言", "算法", "数据库", "总分" };
printTableHead(TABLE_WIDTH, 6);
printTableRow(TABLE_WIDTH, head, sizeof(head) / sizeof(head[0]));
printTableMidLine(TABLE_WIDTH, 6);
sprintf(row[0], "%d", stu[i].num);
sprintf(row[1], "%s", stu[i].name);
sprintf(row[2], "%d", stu[i].cLang);
sprintf(row[3], "%d", stu[i].algo);
sprintf(row[4], "%d", stu[i].database);
sprintf(row[5], "%d", stu[i].sum);
printTableRow(TABLE_WIDTH, row, 6);
printTableTail(TABLE_WIDTH, 6);
}
删除学生信息
void del() {
FILE* fp;
int snum = 0;
char str[16] = "";
system("cls");
printf("请输入学号:");
scanf("%d", &snum);
int i = searchStu(snum);
if (i<0) {
printf("没有找到这名学生!\n");
return;
}
printf("找到这条记录,是否删除?(y/n)");
scanf("%s", str);
if (strcmp(str, "Y") == 0 || strcmp(str, "y") == 0) {
for (int j = i; j < currentCount; j++) {
stu[j] = stu[j + 1];
}
currentCount--;
if (save()) {
printf("删除成功!\n");
}
else {
printf("保存文件失败!\n");
}
}
else {
printf("取消删除!\n");
}
}
修改学生信息
void modify() {
int snum;
system("cls");
printf("请输入要修改的学生的学号: ");
scanf("%d", &snum);
int i = searchStu(snum);
if (i < 0) {
printf("没有找到这名学生!\n");
return;
}
printf("找到了这名学生, 可以修改他的信息!\n");
printf("姓名:");
scanf("%s", stu[i].name);
printf("C 语言:");
scanf("%d", &stu[i].cLang);
printf("算法:");
scanf("%d", &stu[i].algo);
printf("数据库:");
scanf("%d", &stu[i].database);
stu[i].sum = stu[i].cLang + stu[i].algo + stu[i].database;
if (save()) {
printf("修改成功!\n");
}
else {
printf("保存文件失败!\n");
}
}
插入学员信息
在指定学生的后面插入
int snum;
system("cls");
printf("请输入要插入的位置(学号):");
scanf("%d", &snum);
int destIndex = searchStu(snum);
if (destIndex < 0) {
printf("没有这名学生,插入位置错误!\n");
return;
}
struct student t = inputInfo();
int i = searchStu(t.num);
if (i >= 0) {
printf("学号[%d]已经存在! \n", t.num);
return;
}
for (int j = currentCount-1; j > destIndex; j--) {
stu[j + 1] = stu[j];
}
stu[destIndex + 1] = t;
currentCount++;
if (save()) {
printf("插入成功!\n");
} else {
printf("保存文件失败!\n");
}
学生成绩排名
掌握最基础的排序算法-交换排序
void order() {
if (currentCount == 0) {
printf("还没有学生记录!\n");
return;
}
for (int i = 0; i < currentCount - 1; i++) {
for (int j = i + 1; j < currentCount; j++) {
if (stu[i].sum < stu[j].sum) {
struct student t = stu[i];
stu[i] = stu[j];
stu[j] = t;
}
}
}
if (!save()) {
printf("排序后,保存文件失败!\n");
}
else {
show();
}
}
统计学生总数
作业,自己实现哦~
更多项目提升
长按图片扫码进入小程序
相关文章:

【C语言】手写学生管理系统丨附源码+教程
最近感觉大家好多在忙C语言课设~ 我来贡献一下,如果对你有帮助的话谢谢大家的点赞收藏喔! 1. 项目分析 小白的神级项目,99%的程序员,都做过这个项目! 掌握这个项目,就基本掌握 C 语言了! 跳…...

流媒体传输协议HTTP-FLV、WebSocket-FLV、HTTP-TS 和 WebSocket-TS的详细介绍、应用场景及对比
一、前言 HTTP-FLV、WS-FLV、HTTP-TS 和 WS-TS 是针对 FLV 和 TS 格式视频流的不同传输方式。它们通过不同的协议实现视频流的传输,以满足不同的应用场景和需求。接下来我们对这些流媒体传输协议进行剖析。 二、传输协议 1、HTTP-FLV 介绍:基于 HTTP…...

【机器学习】线性回归:从基础到实践的深度解析
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 线性回归:从基础到实践的深度解析引言一、线性回归基础1.1 定义与目…...

短视频开源项目MoneyPrinterTurbo:AI副业搞起来,视频制作更轻松!
目录 引言一、MoneyPrinterTurbo简介二、MoneyPrinterTurbo的核心功能三、MoneyPrinterTurbo的未来发展四、MoneyPrinterTurbo与AI副业五、部署实践1、克隆代码2、创建虚拟环境3、安装依赖4、安装好 ImageMagick5、端口映射6、启动Web界面7、模型配置8、填写主题9、视频生成10、…...

【JAVA】SpringBoot + skywalking 将接口的入参、出参、异常等信息上报到skywalking 链路追踪服务器上
【JAVA】SpringBoot skywalking 将接口的入参、出参、异常等信息上报到skywalking 链路追踪服务器上 1.下载SkyWalking APM https://skywalking.apache.org/downloads/ jdk8 不支持 SkyWalking APM 9.3.0以上版本,所以这里我们下载 9.3.0版本 2.下载 Java Agent …...
[xmake]构建静态库和动态库
xmake 静态库和动态库 在xmake中创建静态库和动态库的方法非常相似。以下是创建静态库和动态库的基本步骤: 创建xmake工程文件(xmake.lua)。 配置工程属性,包括工程名、版本等。 添加源代码文件到工程中。 设置是创建静态库还…...

功能测试 之 单模块测试----轮播图、登录、注册
单功能怎么测? 需求分析 拆解测试点 编写用例 1.轮播图 (1)需求分析 位置:后台--页面--广告管理---广告列表(搜索index页面增加广告位2) 操作完成后需要点击admin---更新缓存,前台页面刷新生效 (2)拆解…...
MyBatis-PageHelper 源码解说
归档 GitHub: MyBatis-PageHelper-源码解说 总说明 源码仓库: https://github.com/pagehelper/Mybatis-PageHelper克隆:git clone https://github.com/pagehelper/Mybatis-PageHelper.git切分支(tag):git checkout m…...

基于uni-app和图鸟UI的智慧校园圈子小程序开发实践
摘要: 随着教育信息化和“互联网教育”的快速发展,智慧校园建设已成为推动校园管理现代化、提高教育教学质量的重要手段。本文介绍了基于uni-app和图鸟UI开发的智慧校园圈子小程序,旨在通过一站式服务、个性化定制、数据互通和安全可靠等特点…...

STM32 keil工程移植到Visual Studio Code环境中编译
1、GCC Vscode 搭建 STM32 开发环境 GCC Vscode 搭建 STM32 开发环境(一)- 环境部署 - 知乎 (zhihu.com) 2、在原有keil工程下找到原本CUBEMX生成的.ioc工程文件 3、将.ioc文件复制一个新的文件夹下双击打开工程,将IDE选为Makefile&…...
细说CountDownLatch
CountDownLatch是Java中提供的一个同步辅助类,它允许一个或多个线程等待其他线程完成操作。在面试中,面试官经常会询问候选人是否在实际项目中使用过CountDownLatch,以评估其对多线程编程和并发控制的理解和经验。本文将详细介绍CountDownLat…...
java-克隆应用
5.2 创建复杂对象 对于某些复杂对象,通过克隆来创建其副本比通过构造函数创建新实例更加高效。例如,当对象包含大量字段或需要进行复杂初始化时,克隆可以显著提高性能。 java 复制代码 class ComplexObject implements Cloneable { private …...

RPC协议
3.8 既然有 HTTP 协议,为什么还要有 RPC 假设我们需要在 A 电脑的进程发一段数据到 B 电脑的进程,我们一般会在代码里使用 Socket 进行编程。 这时候,我们可选项一般也就 TCP 和 UDP 二选一。TCP 可靠,UDP 不可靠。 类似下面这…...

医疗器械3D全景展会在线漫游创造数字化时代的展览新篇章
在数字化浪潮的引领下,VR虚拟网上展会正逐渐成为企业展示品牌实力、吸引潜在客户的首选平台。我们与广交会携手走过三年多的时光,凭借优质的服务和丰富的经验,赢得了客户的广泛赞誉。 面对传统展会活动繁多、企业运营繁忙的挑战,许…...
IP_Endpoint类型在CAPL中的使用
在使用TCP/IP协议栈通信时,创建Socket套接字调用接口函数实现通信的整个过程成为一种主流且便捷的方式。在CAPL中,Client需要创建TCP或UDP套接字,绑定自己的IP地址和一个端口号,作为自己的通信端点。 on key c {clientsocket = tcpOpen(ipGetAddressAsNumber("192.16…...

数据资产与用户体验优化:深入挖掘用户数据,精准分析用户需求与行为,优化产品与服务,提升用户体验与满意度,打造卓越的用户体验,赢得市场认可
一、引言 在数字化时代,数据已经成为企业最宝贵的资产之一。通过深入挖掘和分析用户数据,企业能够精准把握用户需求和行为,从而优化产品与服务,提升用户体验和满意度。这不仅有助于企业在激烈的市场竞争中脱颖而出,还…...

基于TCAD与紧凑模型结合方法探究陷阱对AlGaN/GaN HEMTs功率附加效率及线性度的影响
来源:Investigation of Traps Impact on PAE and Linearity of AlGaN/GaN HEMTs Relying on a Combined TCAD–Compact Model Approach(TED 24年) 摘要 本文提出了一种新型建模方法,用于分析GaN HEMTs的微波功率性能。通过结合工…...
具身智能概念
具身智能作为人工智能发展的一个重要分支,伴随着大模型技术的爆发与硬件成本的降低,即软硬件技术走向成熟,正在成为广泛关注的热门,一时之间,具身智能机器人也成为了科技界新的风向标。 什么是具身智能? …...

C++ 43 之 自增运算符的重载
#include <iostream> #include <string> using namespace std;class MyInt{friend ostream& operator<< (ostream& cout , MyInt& int1); public:MyInt(){this->m_num 0;}// 前置自增: 成员函数实现运算符的重载 返回的是 引用&a…...

计算机网络:1概述、2物理层
目录 概述因特网网络、互连网(互联网)与因特网的区别与关系因特网发展的三个阶段因特网服务提供者(Internet Service Provider,ISP)因特网的标准化工作因特网的管理结构 三种交换电路交换分组交换报文交换 计算机网络性…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...

职坐标物联网全栈开发全流程解析
物联网全栈开发涵盖从物理设备到上层应用的完整技术链路,其核心流程可归纳为四大模块:感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性,例如传感器选型需平衡精度与…...