C++学习(四十)(C语言部分)之 学生管理系统设计
涉及到的:
指针申请内存 结构体
数据结构部分
排序
文件操作
vs2013
数据结构 排序 结构体 指针
功能:
1、人工录入信息
2、删除
3、查找
4、修改
5、全部显示
6、文件的读取和保存
7、排序
设计:
学生信息 学号 名字 年龄 成绩(结构体)
1、数据 用数组存放学生信息 顺序表(数组+size+len实现) 链表(结构体指针实现)
2、增删查改
3、菜单 +提示 +界面
注册 -->注册的用户 密码 存到文件
登录 输入用户名和密码 到文件中找有没有匹配的记录
首先在项目编写过程中,将需要的功能,函数等思路罗列清楚。
大致分为以下四个板块
//******头文件 宏定义 类型定义 全局变量********
//******************函数声明*************************
//*****************主函数****************************
//******************函数定义************************
第一步,对学生信息的录入工作
先将学生属性用结构体存放
将所用到的函数首先在函数声明部分进行声明,之后再函数定义部分对所用到的函数进行定义,并在需要的时候进行调用。
最先做好的部分就是菜单和信息录入
测试结果如下所示:
发现输出有一点问题,之后再做修改。
具体测试代码笔记如下:
//****************头文件 宏定义 类型定义 全局变量********************
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<string.h>
#include<WinBase.h> //学生基本信息
typedef struct student
{
char stuNum[];//学号
char name[];//名字
int age;//年龄
float grade;//成绩
//后续可以继续加 struct student*next;//如果用数组存 那么不需要指针域 链表存 需要指针域
}STU,*PSTU;
//****************函数声明********************
void menu();//菜单
void insertStu(PSTU head);//录入
void findMenu(PSTU head);//查询用菜单
void findByAge(PSTU head);//根据年龄查找信息
//void changeStu();//修改
void printAll(PSTU head);//全部打印
//---------------------------------主函数
void deleStuByNum(PSTU head);//通过学号删除学员信息 void sortByGrade(PSTU head);//按照分数排序 void swap(PSTU a, PSTU b); //交换两个节点 void insertFile(PSTU head);//从文件中读取内容 void setFile(PSTU head);//存档 void freeNode(PSTU head);//释放所有节点 void deleStuByGrade(PSTU head);//通过成绩删除 //******************主函数********************
int main()
{ menu();
return ;
} //****************函数定义********************
//菜单
void menu()
{
//链表
PSTU head=(PSTU)malloc(sizeof(STU));//定义头指针
head->next = NULL;//头结点的next赋值NULL
//录入文件 打开文件并且读取文件内容 (没写完 待补充 )***************
insertFile(head);//读取文件内容
while ()//循环一直进行
{
system("cls");//清屏函数 用于控制台的
printf("**************************\n");
printf("****欢迎进入学生管理系统****\n");
printf("1.录入学生信息\n");
printf("2.查询学生信息\n");
printf("3.修改学生信息\n");
printf("4.删除学生信息\n");
printf("5.打印所有学生信息\n");
printf("6.排序\n");
printf("0.退出\n");
printf("输入你的选择\n\n");
int choice = -;
scanf("%d", &choice);//获取用户用户的操作
switch (choice)
{
case ://录入
insertStu(head);//传递实参
break;
case ://查询
findMenu(head);//查询
break;
case ://修改 先查询 找到位置之后 再修改
//不写
break;
case ://删除 //示例用学号删除学生信息
deleStuByNum(head);
break;
case ://全部打印
printAll(head);
break;
case :
//链表的排序
//默认用学号排序 换成用分数排序
sortByGrade(head);
break;
case ://退出程序
/*
跳转语句 goto
return //跳出这个循环
break//跳出循环 跳出swicth
continue//跳过本轮循环 进入下一轮循环
exit(0);//函数 表示退出这个程序 stdlib.h
*/
//--------------------=========//跳出循环
setFile(head);//退出前存档
//存挡 当前所有内容 写入文件(待补充,,,,,,,,,,,>
//释放所有节点内存(待补充-------------------->
freeNode(head);//释放这个链表所有结点
return;//跳出这个函数
break;
default:
//输入错误
//重新输入
printf("输入错误 请重新输入\n");
Sleep();//休息两秒 Windows.h
//....
break;
}
}
} //录入
void insertStu(PSTU head)
{
PSTU p = (PSTU)malloc(sizeof(STU));
printf("输入学生信息");
printf("输入学号"); scanf("%s", p->stuNum);//录入
printf("输入姓名"); scanf("%s", p->name);
printf("输入年龄"); scanf("%d", &p->age);
printf("输入成绩"); scanf("%f", &p->grade);
//输入完成之后 连接
//p->next = head->next;
//head->next = p;//头插 ///插入的时候同时进行排序
PSTU temp = head;
//插入到合适的位置
while (temp->next != NULL)
{
if (strcmp(temp->next->stuNum, p->stuNum)>)//找到第一个比他大的元素
{
break;
}
temp = temp->next;
}
//如果temp->next==NULL 插入放在里面的话这个节点不会被插入到链表中 因此放在外面
p->next = temp->next;
temp->next = p;//插入
Sleep();//看一下效果
} //全部打印
void printAll(PSTU head)
{
PSTU p = head->next;
while (p != NULL)
{
printf("学号%10s\t名字%10s\t年龄%5d\t分数%.2f\n", p->stuNum, p->name, p->age, p->grade);
p = p->next;
}
//printf("学号\t\t名字\t\t年龄\t\t分数\n");//这个需要另外对齐
//while (p != NULL)
//{
// printf("%s\t%s\t%d\t%.2f\n", p->stuNum, p->name, p->age, p->grade);
// p = p->next;
//}
Sleep();//休息一会
} //查询用菜单
void findMenu(PSTU head)
{
system("cls");
printf("请输入你要查询的方式");
printf("1.按照年龄查询"); int choice;
scanf("%d", &choice);
switch (choice)
{
case ://根据年龄查询
//通过年龄区间 得到信息 可以写函数 也可以直接写
break;
}
} //根据年龄查找信息
void findByAge(PSTU head)
{
//1.根据年龄查询
//2.根据区间查询
printf("请输入一个年龄区间");
int x, y;//年龄
scanf("%d %d", &x, &y);
if (x >= y)
{
for (PSTU temp = head->next; temp != NULL; temp = temp->next)
{
if (temp->age >= y&&temp->age <= x)
{
printf("学号%10s\t名字%10s\t年龄%5d\t分数%.2f\n", temp->stuNum, temp->name, temp->age, temp->grade);
}
}
}
else//x<=y
{
//自己补齐
}
Sleep();
} //通过学号删除学员信息
void deleStuByNum(PSTU head)
{
PSTU p = head;
char stuNum[];
printf("输入你要删除的学员的学号");
scanf("%s", stuNum);
//删除一个节点 要删除位置前面的结点 //for (; p->next != NULL; p = p->next)
//{
// if (strmp(p->next->stuNum, stuNum) == 0)
// {
// break;
// }
//}
//if (p->next!=NULL)
//{
// PSTU q = p->next;
// p->next = q->next;
// free(q);//释放结点
// //如果多个学号相同的同学
// printf("删除成功");
//}
//else
//{
// printf("找不到对应的记录 删除失败\n");
//} for (; p->next != NULL; )
{
if (strcmp(p->next->stuNum, stuNum) == )
{
PSTU q = p->next;
p->next = q->next;
free(q);//释放结点
//如果多个学号相同的同学
//printf("删除成功");
}
else
{
p = p->next;//这句不直接放在外面的原因 避免少比较一个元素
//比如说 A->B->C->D
//p 刚刚开始指向A 删除B之后 A->C->D
//p往后移动 C就没有参与比较 所以为了避免这种情况 p=p->next放在else中
}
}
Sleep();
} //按照分数排序
void sortByGrade(PSTU head)
{
//冒泡 插入 选择 快速
// 冒泡 从头到尾 如果相邻元素位置有问题 交换
//插入 将后面的一个结点插入到前面的有序位置中
//选择 交换两个节点 每次找剩下那个最小的进行交换
//快速 一分为2 分开进行快速排序 //快速 冒泡 选择 交换
//做法 :找到两个位置 进行交换 //链表的循环条件稍微改一下
//选择排序
PSTU p = head->next;//第一个节点
PSTU q, min;
while (p != NULL)
{
min = p;//刚刚开始指向p的位置
q = p->next;//从p的后面开始找
while (q != NULL)
{
//if (strcmp(q->stuNum, min->stuNum) < 0)
if (q->grade<min->grade)
{
min = q;//标记最小
}
q = q->next;
}
if (min == NULL||min == p);//不需要交换
else swap(p, min);//交换两个节点的数据
p = p->next;
} } //交换两个节点 写一个函数
void swap(PSTU a, PSTU b)
{
char stuNum[];//学号
char name[];//名字
int age;//年龄
float grade;//成绩
strcpy(stuNum, a->stuNum);
strcpy(a->stuNum, b->stuNum);
strcpy(b->stuNum, stuNum);
strcpy(name, a->name);
strcpy(a->name, b->name);
strcpy(b->name, name);
age = a->age;
a->age = b->age;
b->age = age;
grade = a->grade;
a->grade = b->grade;
b->grade = grade;
} //文件操作 -->数据存放文件中(保留数据)
//读档
void insertFile(PSTU head)//从文件中读取内容
{
FILE *fp = fopen("student.txt", "r");//rwa 三选一
//r 文件不存在 打开失败
//w 文件不存在 创建文件 但是文件存在 清空文件内容
if (fp == NULL)
{
fp = fopen("student.txt", "w");//创建新文件
fclose(fp);
return;
}
//学号 名字 年龄 成绩
STU temp, *p;
while ()//循环读取
{
fscanf(fp, "%s %s %d %f", temp.stuNum, temp.name, &temp.age, &temp.grade);//读取内容
if (feof(fp)) break;//如果文件读到末尾 返回1
//feof 文件中有三个数据 当读完第三个数据的时候不会返回1
//读到第四个的时候有问题 p = (PSTU)malloc(sizeof(STU));
*p = temp;//赋值
//将这个节点 连到链表上
PSTU q = head;
//插入到合适的位置
while (q->next != NULL)
{
if (strcmp(q->next->stuNum, p->stuNum)>)//找到第一个比他大的元素
{
break;
}
q = q->next;
}
//如果temp->next==NULL 插入放在里面的话这个节点不会被插入到链表中 因此放在外面
p->next = q->next;
q->next = p;//插入 }
fclose(fp);//关闭文件 } //存档
void setFile(PSTU head)
{
//写入 w a
FILE *fp = fopen("student.txt", "w");//清空原内容
PSTU p = head->next;
while (p != NULL)
{
fprintf(fp,"%s %s %d %.2f\n", p->stuNum, p->name, p->age, p->grade);//写入文件
p = p->next;
}
fclose(fp);
} void freeNode(PSTU head)//释放所有节点
{
PSTU temp = head;
while (head != NULL)
{
temp = head;
head = head->next;
free(temp);//释放节点
}
} //通过成绩删除
void deleStuByGrade(PSTU head)
{
PSTU arr[];
int len = ;
int size = ;
//准备数组
float Grade;
printf("输入的你要删除的学生的成绩");
scanf("%f", &Grade); //取地址
PSTU p = head->next;
while (p != NULL)
{
if (p->grade < Grade + && p->grade>Grade - )// 浮点型 存的都是近似值 给一个区间
{
if (len < size) arr[len++] = p;//存放符合要求一个结点的位置
}
}
//找到所有符合要求的节点
for (int i = ; i < len; ++i)
{
printf("编号%d--->学号%s,姓名%s,年龄%d,成绩%.2f",i, arr[i]->stuNum, arr[i]->name, arr[i]->age, arr[i]->grade);
}
printf("输入你要删除的元素的编号");
int choice;
scanf("%d", &choice);
if (choice >= && choice < len)//说明有删除的元素
{
//找到结点并且删除就可以了
//arr[choice];//结点的地址
//找前面那个结点 然后删除
PSTU temp = head;
while (temp!=NULL)
{
//找要删除的前面那个结点的位置
if (temp->next == arr[choice])
{
temp->next = arr[choice]->next;
free(arr[choice]);
break;
}
temp = temp->next;
}
}
}
/*
//指针申请内存 结构体
//数据结构部分
//排序 time 函数
gettickcount 开始获取一次时间 结束的获取一次时间
时间差 --->运行时间 //测试
DWORD time1 = GetTickCount();
Sleep(2000);
DWORD time2 = GetTickCount();
printf("%ld", time2 - time1);
getchar(); 1.算法优化 -->排序
2.存储优化 --->数组 单链表 双链表
数组 省内存 中间插入 开头插入 比较麻烦 尾端插入效率高
查找 访问从前往后 也可以从后往前
单链表 插入很方便 内存不是很省 没有长度限制
访问 不是很方便
双链表 插入方便 内存不是很省
访问可以从前往后 也可以从后往前
3.计算 右移代替除以2
注:其中部分功能并没有实现,还有一些是需要补充的,等以后有时间再补充吧
部分成功展示:
2019-04-04 10:19:07
C++学习(四十)(C语言部分)之 学生管理系统设计的更多相关文章
- Salesforce LWC学习(四十) dynamic interaction 浅入浅出
本篇参考: Configure a Component for Dynamic Interactions in the Lightning App Builder - Salesforce Light ...
- shell学习四十九天----进程建立
进程 前言:进程指的是运行中程序的一个实例.新进程由fork()与execve()等系统调用所起始,然后运行,知道他们下达exit()系统调用为止. linux系统都支持多进程.尽管计算机看起来像是一 ...
- shell学习四十天----awk的惊人表现
awk的惊人表现 awk能够胜任差点儿全部的文本处理工作. awk 调用 1.调用awk: 方式一:命令行方式 awk [-F field-separator ] 'commands' inp ...
- Java开发学习(四十)----MyBatisPlus入门案例与简介
一.入门案例 MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发.提供效率. SpringBoot它能快速构建Spring开发环境用以整合其他技术,使用起来 ...
- shell 学习四十五天---xargs
当 find 产生一个文件列表时,该列表提供给另一个命令有时是很有用的.案例: $touch abc.c erd.c oiy.c $ll ./erd.c ./abc.c ./oiy.c $find - ...
- Salesforce LWC学习(四) 父子component交互 / component声明周期管理 / 事件处理
我们在上篇介绍了 @track / @api的区别.在父子 component中,针对api类型的变量,如果声明以后就只允许在parent修改,son component修改便会导致报错. sonIt ...
- Python学习笔记(十二)—Python3中pip包管理工具的安装【转】
本文转载自:https://blog.csdn.net/sinat_14849739/article/details/79101529 版权声明:本文为博主原创文章,未经博主允许不得转载. https ...
- Spark(四十六):Spark 内存管理之—OFF_HEAP
存储级别简介 Spark中RDD提供了多种存储级别,除去使用内存,磁盘等,还有一种是OFF_HEAP,称之为 使用JVM堆外内存 https://github.com/apache/spark/blo ...
- PHP学习笔记(14)班级和学生管理---学生
两个文件夹,一个班级cls,一个学生stu. 两个表,一个班级cls,一个学生stu. 每个文件夹里有7个php文件:主界面stu.php-------增add.php,insert.php----- ...
随机推荐
- 单元测试系列之六:JUnit5 技术前瞻
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6868495.html JUnit ...
- BZOJ 1269 文本编辑器editor(伸展树)
题意 https://www.lydsy.com/JudgeOnline/problem.php?id=1269 思路 伸展树(\(\text{splay}\))功能比较齐全的模板,能较好的体现 \( ...
- LINQ之路15:LINQ Operators之元素运算符、集合方法、量词方法
本篇继续LINQ Operators的介绍,包括元素运算符/Element Operators.集合方法/Aggregation.量词/Quantifiers Methods.元素运算符从一个sequ ...
- 关系数据库、NoSQL和NewSQL数据库产品分类
- Apache web服务器(LAMP架构)
Apache web服务器(LAMP架构) apache介绍 1).世界上使用率最高的网站服务器,最高时可达70%:官方网站:apache.org 2).http 超文本协议 HTML 超文本标记语言 ...
- jquery之div模拟textarea文本域轻松实现高度自适应
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- [原][算法][earth]三段smooth,传入时间,返回距离。仿谷歌视角飞跃处理
算法需求: 传入[0~1]的时间time,返回[0~1]的路程. 整个路程distance[0~1]分为三段路径: 第一段:在0.25time的时间里,速度从0,位置从distance:0加速移动到距 ...
- [python](windows)分布式进程问题:pickle模块不能序列化lambda函数
运行错误:_pickle.PicklingError: Can't pickle <function <lambda> at 0x000002BAAEF12F28>: attr ...
- Kali linux 2016.2(Rolling)里安装OpenVAS
不多说,直接上干货! 本博文,是在Kali 2.0 linux里,安装OpenVAS. 前言 OpenVAS是一款开放式的漏洞评估工具,主要用来检测目标网络或主机的安全性.与安全焦点的X-Scan工具 ...
- linux-Centos7安装python3并与python2共存
1.查看是否已经安装Python CentOS 7.2 默认安装了python2.7.5 因为一些命令要用它比如yum 它使用的是python2.7.5. 使用 python -V 命令查看一下是否安 ...