深圳幻海软件技术有限公司 欢迎您!

C语言——学生信息管理系统

2023-06-29

目录功能展示界面展示 所有功能模块:功能1:菜单模块(显示功能菜单)功能2:增加学生信息功能3:输出学生信息(查看所有学习信息)功能4:修改学生信息功能5:删除学生信息功能6:查询单个学生信息功能7:排序学习信息(按照学号升序排序)功能8:退出管理系统 心得分享 过程梳

目录

功能展示

界面展示 

所有功能模块:

功能1:菜单模块(显示功能菜单)

功能2:增加学生信息

功能3:输出学生信息(查看所有学习信息)

功能4:修改学生信息

功能5:删除学生信息

功能6:查询单个学生信息

功能7:排序学习信息(按照学号升序排序)

功能8:退出管理系统

 心得分享 

过程梳理

个人总结

学生管理系统(完整代码)

main.cpp 

student.h

student.cpp


功能展示

界面展示 

 

所有功能模块:


功能1:菜单模块(显示功能菜单)


功能2:增加学生信息


功能3:输出学生信息(查看所有学习信息)


功能4:修改学生信息

第一步:修改信息

第二步:查询验证


功能5:删除学生信息

第一步:删除信息

第一步:查询验证


功能6:查询单个学生信息

  1. 按照学号查询:

  1. 按照姓名查询:

  1. 查询为空:


功能7:排序学习信息(按照学号升序排序)

在排序之前,先增加几条数据:

执行排序:

验证结果(该数据无法验证是否执行头排序)

再插入一条比第一条小的数据(用于执行头排序):

执行(头)排序:

验证结果:


功能8:退出管理系统


 心得分享 

过程梳理

  1. 首先要根据需求分析,将各个功能模块罗列出来

  1. 数据建模,对数据进行封装,创建一个student结构体,添加我们需要的各种数据。

​​​​​

  1. 创建一个可以循环输入命令的菜单,并且可以退出,还可以检查输入的指令是否匹配。
  2. 然后一个个功能模块实现就可以了。但要注意实现功能的顺序。(写功能也要有顺序,这样可以事半功倍)
  3. 第一个功能,肯定就是添加了,每当需要添加的时候,就需要申请一块内存,创建一个student结构体,并赋予相应的数据。
  4. 第二个功能,就是打印全部数据。
  5. 第三个功能,实现单个数据的查询。
  6. 第四个功能,实现单个数据的删除。(删除和修改都差不多)
  7. 第五个功能,实现单个数据的修改。
  8. 第六个功能,也就是最难的功能——链表排序
  9. 最后,对细节进行处理。

个人总结

  1. 当思维混乱的时候,不妨画图来理解。
  2. 写循环时,一定要明确跳出的逻辑和循环的次数和迭代方法。
  3. 在实现功能的时候,还需要考虑特殊情况!边界条件的处理尤其重要。(在排序的时候,一定要考虑多个因素)
  4. 总体难度不大,但是需要一步一步去实现,更多的是考验对细节的处理,后面又看了别人的实现方法,发现自己的思维方式还是比较呆板,别人几行就可以搞定的,自己还是用了各种if分支和for循环才搞定,还得加强自己的思维能力,多刷算法!

学生管理系统(完整代码)

 

main.cpp 

  1. # include "student.h"
  2. int main(){
  3. StudentNode* s = NULL;
  4. int command;
  5. while (true)
  6. {
  7. myMenu(); // 展示菜单
  8. scanf("%d", &command); // 输入
  9. switch (command)
  10. {
  11. case 1:// 增加学生信息
  12. AddStudent(&s);
  13. break;
  14. case 2:// 删除学生信息
  15. DeleteStudent(&s);
  16. break;
  17. case 3:// 修改学生信息
  18. UpdateStudent(&s);
  19. break;
  20. case 4:// 查询学生信息 (可按照姓名和学号)
  21. SearchStudent(&s);
  22. break;
  23. case 5:// 输出学生信息 (打印所有学生信息)
  24. MyPrint(s);
  25. break;
  26. case 6:// 排序学生信息 (按照学号升序排序)
  27. MySort(&s);
  28. break;
  29. case 0:// 退出管理系统
  30. exit();
  31. break;
  32. default : //输入有误
  33. error();
  34. break;
  35. }
  36. system("pause");
  37. }
  38. }

 student.h

  1. #pragma once
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <assert.h>
  5. typedef int STDateTypeOne;
  6. typedef char STDateTypeTow;
  7. // 学生
  8. typedef struct StudentNode
  9. {
  10. int ID; // 学号
  11. int Score; // 排名
  12. char Name[50]; // 姓名
  13. char Sex[10]; // 性别
  14. char Profession[50]; // 专业
  15. char Phone[20]; // 电话号码
  16. char Q[20]; // QQ
  17. struct StudentNode* next; // 指针域
  18. }StudentNode;
  19. // 主菜单界面
  20. void myMenu();
  21. // 退出系统
  22. void exit();
  23. // 命令有误
  24. void error();
  25. // ----------------------------------CRUD模块
  26. void AddStudent(StudentNode** s); // 添加
  27. void DeleteStudent(StudentNode** s); // 删除
  28. void UpdateStudent(StudentNode** s); // 更新
  29. void SearchStudent(StudentNode** s); // 查询
  30. // ----------------------------------其他模块
  31. void MyPrint(StudentNode* s); // 输出学生信息 (打印所有学生信息)
  32. void MySort(StudentNode** s); // 排序学生信息 (按照学号升序排序)

 student.cpp

  1. #include "student.h"
  2. // 字符判断
  3. int MyStrcmp(const char* str1, const char* str2)
  4. {
  5. assert(NULL != str1);
  6. assert(NULL != str2);//防御性编程
  7. while (*(unsigned char*)str1 == *(unsigned char*)str2)
  8. {
  9. if (*(unsigned char*)str1 != '\0')
  10. {
  11. return 0;//当*(unsigned char*)str1 ==*(unsigned char*)str2==‘\0'时两个字符串完全相等
  12. }
  13. str1++; //比较下个字符
  14. str2++;
  15. }
  16. //*(unsigned char*)str1 与*(unsigned char*)str2的差值与返回值正负匹配
  17. return *(unsigned char*)str1 - *(unsigned char*)str2;
  18. }
  19. // 菜单
  20. void myMenu(){
  21. system("cls");
  22. printf("****************************************************************\n");
  23. printf("*********** \033[34m学生信息管理系统 \033[30m ***********\n");
  24. printf("----------------------------------------------------------------\n");
  25. printf("*********** \033[32m 1 \033[30m---- 增加学生信息 ***********\n");
  26. printf("*********** \033[32m 2 \033[30m---- 删除学生信息 ***********\n");
  27. printf("*********** \033[32m 3 \033[30m---- 修改学生信息 ***********\n");
  28. printf("*********** \033[32m 4 \033[30m---- 查询学生信息 ***********\n");
  29. printf("*********** \033[32m 5 \033[30m---- 输出学生信息 ***********\n");
  30. printf("*********** \033[32m 6 \033[30m---- 排序学生信息 ***********\n");
  31. printf("*********** \033[32m 0 \033[30m---- 退出管理系统 ***********\n");
  32. printf("****************************************************************\n");
  33. printf("\033[31m");
  34. printf("请选择想要实现的功能(数字):");
  35. }
  36. // 退出管理系统
  37. void exit()
  38. {
  39. system("cls");
  40. printf("欢迎下次使用学生信息管理系统!\n");
  41. exit(0); // 结束程序
  42. }
  43. // 提示输入错误
  44. void error(){
  45. printf("请输入对应指令!\n");
  46. }
  47. // ----------------------------------CRUD模块
  48. void AddStudent(StudentNode** s){
  49. int ID; // 学号
  50. int Score; // 排名
  51. char Name[50]; // 姓名
  52. char Sex[10]; // 性别
  53. char Profession[50]; // 专业
  54. char Phone[20]; // 电话号码
  55. char Q[20]; // QQ
  56. // 创建新节点
  57. StudentNode* newnode = (StudentNode*)malloc(sizeof(StudentNode)); //将申请的空间---强转为 指针变量
  58. // 输入数据
  59. printf("请输入新增学生的相关信息:\n");
  60. printf("学号:");
  61. scanf("%d", &newnode->ID); // 输入
  62. printf("排名:");
  63. scanf("%d", &newnode->Score); // 输入
  64. printf("姓名:");
  65. scanf("%s", &newnode->Name); // 输入
  66. printf("性别: ");
  67. scanf("%s", &newnode->Sex); // 输入
  68. printf("专业: ");
  69. scanf("%s", &newnode->Profession); // 输入
  70. printf("电话号码:");
  71. scanf("%s", &newnode->Phone); // 输入
  72. printf("QQ号: ");
  73. scanf("%s", &newnode->Q); // 输入
  74. newnode->next = NULL;
  75. // 尾插
  76. if(*s == NULL){
  77. *s = newnode;
  78. }
  79. else{
  80. printf("添加中...\n");
  81. //找到尾节点
  82. StudentNode* tp = *s;
  83. StudentNode* tmp;
  84. while(tp->next != NULL){
  85. tmp = tp->next;
  86. tp = tmp;
  87. }
  88. tp->next = newnode;
  89. }
  90. printf("添加成功!\n");
  91. }
  92. void DeleteStudent(StudentNode** s){
  93. //判断链表是不是空
  94. if(*s == NULL){
  95. printf("当前还没有任何数据!\n ");
  96. return;
  97. }
  98. // 展示所以数据
  99. MyPrint(*s);
  100. int id;
  101. // 选择删除的数据
  102. printf("您要删除第几条信息: ");
  103. scanf("%d", &id); // 输入
  104. // 进行删除
  105. StudentNode* tp = *s;
  106. StudentNode* flag= *s;
  107. // 删头节点
  108. if(id == 1){
  109. StudentNode* p = (*s)->next;
  110. free(*s);
  111. *s = p;
  112. printf("删除成功!\n");
  113. return;
  114. }
  115. for(int i = 1; i< id; i++){
  116. flag = tp;
  117. tp = tp->next;
  118. }
  119. flag->next = tp->next;
  120. free(tp);
  121. printf("删除成功!\n");
  122. }
  123. void UpdateStudent(StudentNode** s){
  124. //判断链表是不是空
  125. if(*s == NULL){
  126. printf("当前还没有任何数据!\n ");
  127. return;
  128. }
  129. // 展示所以数据
  130. MyPrint(*s);
  131. int id;
  132. // 选择修改的信息
  133. printf("您要修改第几条信息: ");
  134. scanf("%d", &id); // 输入
  135. // 进行修改
  136. StudentNode* tp = *s;
  137. StudentNode* flag= *s;
  138. for(int i = 1; i< id; i++){
  139. tp = tp->next;
  140. }
  141. // 请输入您要修改的数据
  142. printf("请输入您要修改的数据 :\n");
  143. printf("学号:");
  144. scanf("%d", &tp->ID); // 输入
  145. printf("排名:");
  146. scanf("%d", &tp->Score); // 输入
  147. printf("姓名:");
  148. scanf("%s", &tp->Name); // 输入
  149. printf("性别: ");
  150. scanf("%s", &tp->Sex); // 输入
  151. printf("专业: ");
  152. scanf("%s", &tp->Profession); // 输入
  153. printf("电话号码:");
  154. scanf("%s", &tp->Phone); // 输入
  155. printf("QQ号: ");
  156. scanf("%s", &tp->Q); // 输入
  157. // 修改成功!
  158. printf("修改成功! \n");
  159. }
  160. void SearchStudent(StudentNode** s){
  161. //判断链表是不是空
  162. if(*s == NULL){
  163. printf("当前还没有任何数据!\n ");
  164. return;
  165. }
  166. StudentNode* p = *s;
  167. int choice;
  168. int myid; // 学号
  169. char myname[50]; // 姓名
  170. // 选择查询方法
  171. printf("请选择查询方式(0:学号 / 1:姓名) : ");
  172. scanf("%d", &choice); // 输入
  173. // 学号查询
  174. if(choice == 0){
  175. printf("请输入查询的学号 : ");
  176. scanf("%d", &myid); // 输入
  177. while(1){
  178. // 边界判断
  179. if(p->next == NULL){
  180. if(p->ID == myid){
  181. printf("__________________________________________");
  182. printf("_______________________________________\n");
  183. printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
  184. p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
  185. }else{
  186. printf("您所查找的学生不存在!\n");
  187. }
  188. break;
  189. }
  190. // 判断学号
  191. if(p->ID == myid){
  192. printf("__________________________________________");
  193. printf("_______________________________________\n");
  194. printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
  195. p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
  196. break;
  197. }
  198. // 继续遍历
  199. p = p->next;
  200. }
  201. return;
  202. }
  203. if(choice == 1){
  204. printf("请输入查询的姓名 : ");
  205. scanf("%s", &myname); // 输入
  206. while(1){
  207. // 边界判断
  208. if(p->next == NULL){
  209. // 判断姓名
  210. int i = MyStrcmp(p->Name, myname);
  211. if(i == 0){
  212. printf("|学号\t|排名\t|姓名\t|性别\t|专业\t\t|电话\t\t|QQ\t\t|\n");
  213. printf("__________________________________________");
  214. printf("_______________________________________\n");
  215. printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
  216. p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
  217. break;
  218. }
  219. else{
  220. printf("您所查找的学生不存在!\n");
  221. }
  222. break;
  223. }
  224. // 判断姓名
  225. int i = MyStrcmp(p->Name, myname);
  226. if(i == 0){
  227. printf("|学号\t|排名\t|姓名\t|性别\t|专业\t\t|电话\t\t|QQ\t\t|\n");
  228. printf("__________________________________________");
  229. printf("_______________________________________\n");
  230. printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
  231. p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
  232. break;
  233. }
  234. // 继续遍历
  235. p = p->next;
  236. }
  237. return;
  238. }
  239. printf("请输入正常的指令!\n");
  240. }
  241. // ----------------------------------其他模块
  242. void MyPrint(StudentNode* s){
  243. system("cls");
  244. StudentNode* p = s;
  245. if(!p){
  246. printf("暂无任何信息!\n");
  247. return;
  248. }
  249. printf("|学号\t|排名\t|姓名\t|性别\t|专业\t\t|电话\t\t|QQ\t\t|\n");
  250. while (p != NULL)
  251. {
  252. printf("__________________________________________");
  253. printf("_______________________________________\n");
  254. printf("|%d\t|%d\t|%s\t|%s\t|%s\t\t|%s\t\t|%s\t\t|\n",
  255. p->ID, p->Score, p->Name, p->Sex, p->Profession, p->Phone, p->Q);
  256. p = p->next;
  257. }
  258. }
  259. //=============冒泡排序====================升序
  260. void MySort(StudentNode** s){
  261. StudentNode* p = *s;
  262. StudentNode* temp;
  263. int lenth = 0;
  264. // 判断特殊情况 长度为1
  265. if((p -> next == NULL))
  266. {
  267. printf("长度为1,无需排序!\n");
  268. return;
  269. }
  270. // 判断特殊情况 长度为2
  271. if((p -> next -> next == NULL))
  272. {
  273. if(p->ID < p->next->ID){
  274. temp = p; // 保存头节点
  275. *s = (*s)->next; // 头节点换为下一个节点
  276. (*s)->next = temp;
  277. (*s)->next->next = NULL;
  278. }
  279. printf("排序完成! \n");
  280. return;
  281. }
  282. // 获取长度
  283. while(1) {
  284. lenth++;
  285. if(p->next == NULL){
  286. // 退出
  287. break;
  288. }
  289. p = p->next;
  290. }
  291. printf("长度为%d !\n", lenth);
  292. // 冒泡排序
  293. StudentNode* head = *s;
  294. StudentNode* pre = *s; // 当前
  295. StudentNode* cur = (*s)->next; // 当前 +1
  296. StudentNode* next = (*s)->next->next; // 当前 + 2
  297. StudentNode* end = NULL;
  298. for (int i = lenth; i >= 0; i--) {
  299. pre = head;
  300. cur = pre->next;
  301. next = cur->next;
  302. while(next != NULL) {
  303. if (cur->ID > next->ID) {
  304. cur->next = next->next;
  305. pre->next = next;
  306. next->next = cur;
  307. next = cur->next;
  308. pre = pre->next;
  309. }
  310. else {
  311. pre = pre->next;
  312. cur = cur->next;
  313. next = next->next;
  314. }
  315. }
  316. }
  317. // 头结点 排序
  318. head = *s;
  319. cur = *s; // 当前
  320. // cur到尾巴
  321. while(cur->next != NULL){
  322. // 大于上一个,小于下一个
  323. if(head->ID > cur->ID && head->ID < cur->next->ID ){
  324. // 头节点换为下一个节点
  325. *s = (*s)->next;
  326. // 插入 head
  327. temp = cur->next;
  328. cur->next = head;
  329. head->next = temp;
  330. printf("头排序完成!\n");
  331. printf("排序完成!\n");
  332. return;
  333. }
  334. cur = cur->next; // 往下走
  335. }
  336. // 单独比较尾巴
  337. if(head->ID > cur->ID){
  338. // 头节点换为下一个节点
  339. *s = (*s)->next;
  340. cur->next = head;
  341. head->next = NULL;
  342. printf("头排序完成!\n");
  343. }
  344. printf("排序完成!\n");
  345. }
文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览48550 人正在系统学习中