功能分区欢迎界面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("*\t9.退出系统\t\t*\n"); printf("*********************************\n");}录入学生信息void InputStudent(Node *head){ Node* fresh = malloc(sizeof(Node)); fresh->next = NULL; printf("请录入学生的学号,姓名,成绩:\n"); scanf("%d%s%d", &fresh->student.stuNum, fresh->student.name, &fresh->student.score); saveStudent(head); // 保存学生信息(录入一个保存一个) Node* move = head;//找到结点尾部 while (move->next != NULL) { move = move->next; } move->next = fresh;//将学生信息放入链表尾部 //暂停程序 system("pause"); //清空控制台 system("cls");}打印学生信息void PrintStudent(Node* head){ Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.score); move = move->next; } //暂停程序 system("pause"); //清空控制台 system("cls");}统计学生人数void countStudent(Node* head){ int count = 0; Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { move = move->next; count++; } printf("学生的总人数为:%d", count); // 暂停程序 system("pause"); //清空控制台 system("cls");}查找学生信息void findStudent(Node* head){ printf("请输入需要查找的学生的学号:"); int stuNum; scanf("%d", &stuNum); Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { if (stuNum == move->student.stuNum) { printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.score); // 暂停程序 system("pause"); //清空控制台 system("cls"); return;//break只是跳出循环,用return直接跳出函数 } move = move->next; } printf("未找到学生信息\n"); // 暂停程序 system("pause"); //清空控制台 system("cls");}修改学生信息void modifyStudent(Node* head) { printf("请输入要修改的学生的学号:"); int stuNum; scanf("%d", &stuNum); Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { if (stuNum == move->student.stuNum) { printf("请输入学生姓名,成绩\n"); scanf("%s%d", move->student.name,&move->student.score); printf("修改成功"); // 暂停程序 system("pause"); //清空控制台 system("cls"); return; } move = move->next; } printf("未找到学生信息"); // 暂停程序 system("pause"); //清空控制台 system("cls");}删除学生信息void deleteStudent(Node* head) { printf("请输入需要删除的学生学号:"); int stuNum; scanf("%d", &stuNum); Node* move = head; while (move->next!= NULL) { if (move->next->student.stuNum == stuNum) { Node* temp = move->next;//将需要删除额结点赋给临时结点,方便后面释放结点 move->next = move->next->next; free(temp);//释放掉需要删除的结点 temp = NULL;//临时结点内容被释放后,结点指针指向空 saveStudent(head);//同步文件,重新存入删除后的新链表 printf("删除成功"); // 暂停程序 system("pause"); //清空控制台 system("cls"); return; } move = move->next; } printf("未找到学生");}按成绩排序void sortStudent1(Node* head) { Node* move = NULL; Node* save = NULL; for (Node* turn = head->next; turn->next != NULL; turn = turn->next)//冒泡降序,控制轮数为n-1 { for (move = head->next; move->next != save; move = move->next) { if (move->student.score < move->next->student.score) { Student temp; temp = move->student; move->student = move->next->student; move->next->student = temp; } } save = move; } PrintStudent(head);//打印排序后的学生成绩}按学号排序void sortStudent2(Node* head) { Node* move = NULL; Node* save = NULL; for (Node* turn = head->next; turn->next != NULL; turn = turn->next)//冒泡升序,控制轮数为n-1 { for (move = head->next; move->next != save; move = move->next) { if (move->student.stuNum > move->next->student.stuNum) { Student temp; temp = move->student; move->student = move->next->student; move->next->student = temp; } } save = move; } PrintStudent(head);//打印排序后的学生成绩}保存学生信息void saveStudent(Node* head){ //打开文件 FILE* file = fopen("./stu.info", "w");//定义一个文件类型的指针file指向打开的文件(文件名为stu.info) // ./表示相对路径,即当前代码文件存在哪,那么这个被打开(创建)的文件就放在哪 if (file == NULL) { printf("打开文件失败\n"); return; } Node* move = head->next; while (move != NULL) { //将结构体写入文件 if (fwrite(&move->student, sizeof(Student), 1, file) != 1) { printf("保存%s出现错误\n", move->student.name); } move = move->next; } //关闭文件 fclose(file); // 暂停程序 system("pause"); //清空控制台 system("cls");}载入学生信息程序开始即从保存的文件中读取上次保存的信息,避免重复读入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->student, sizeof(Student), 1, file)==1) { move->next = fresh; move = fresh;//move指针移动(始终在最后一个结点位置) fresh = malloc(sizeof(Node));//再次创捷一个新的结点fresh fresh->next = NULL; } free(fresh);//最后多定义了一个结点fresh,要把它释放掉 //关闭文件 fclose(file); printf("读取成功\n");}完整代码头文件#pragma once#include<stdio.h>#include<stdlib.h>#include<conio.h>//学生信息typedef struct _Student{ int stuNum; char name[20]; int score;}Student;//节点信息typedef struct _Node{ Student student; struct _Node* next;}Node;//界面void Welcome();//录入学生信息void InputStudent(Node* head);//打印学生信息void PrintStudent(Node* head);//统计学生人数void countStudent(Node* head);//查找学生信息void findStudent();//持久保存学生信息void saveStudent(Node* head);//程序启动时读入文件(避免重复输入)void loadStudent(Node* head);//修改学生信息void modifyStudent(Node* head);//删除学生信息void deleteStudent(Node* head);//按成绩排序void sortStudent1(Node* head);//按学号排序void sortStudent2(Node* head);main()#include"学生管理系统.h"int main(){ //创建头结点(只需创建一次) Node* head = malloc(sizeof(Node)); head->next = NULL; loadStudent(head);//程序启动时读入文件(避免重复输入) while (1) { Welcome();//创建界面 //从键盘接收一个字符(不用按回车) printf_s("请选择功能:\n"); char ch = _getch(); switch (ch) { /*case '0'://保存学生信息 saveStudent(head); break;*/ 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'://按成绩排序 sortStudent1(head); break; case '8'://按学号排序 sortStudent2(head); break; case '9'://退出系统 system("cls"); printf("欢迎下次使用,Bye Bye"); exit(0);//或者写returns default: break; } } return 0;}//欢迎界面void Welcome(){ printf("*********************************\n"); printf("*\t学生成绩管理系统\t\n"); printf("*********************************\n"); printf("*\t请选择功能列表\t\t\n"); printf("*********************************\n"); //printf("*\t0.保存学生信息\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("*\t9.退出系统\t\t*\n"); printf("*********************************\n");}//录入学生信息void InputStudent(Node *head){ Node* fresh = malloc(sizeof(Node)); fresh->next = NULL; printf("请录入学生的学号,姓名,成绩:\n"); scanf("%d%s%d", &fresh->student.stuNum, fresh->student.name, &fresh->student.score); saveStudent(head); // 保存学生信息(录入一个保存一个) Node* move = head;//找到结点尾部 while (move->next != NULL) { move = move->next; } move->next = fresh;//将学生信息放入链表尾部 //暂停程序 system("pause"); //清空控制台 system("cls");}void PrintStudent(Node* head){ Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.score); move = move->next; } //暂停程序 system("pause"); //清空控制台 system("cls");}void countStudent(Node* head){ int count = 0; Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { move = move->next; count++; } printf("学生的总人数为:%d", count); // 暂停程序 system("pause"); //清空控制台 system("cls");}void findStudent(Node* head){ printf("请输入需要查找的学生的学号:"); int stuNum; scanf("%d", &stuNum); Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { if (stuNum == move->student.stuNum) { printf("学号:%d 姓名:%s 成绩:%d\n", move->student.stuNum, move->student.name, move->student.score); // 暂停程序 system("pause"); //清空控制台 system("cls"); return;//break只是跳出循环,用return直接跳出函数 } move = move->next; } printf("未找到学生信息\n"); // 暂停程序 system("pause"); //清空控制台 system("cls");}void saveStudent(Node* head){ //打开文件 FILE* file = fopen("./stu.info", "w");//定义一个文件类型的指针file指向打开的文件(文件名为stu.info) // ./表示相对路径,即当前代码文件存在哪,那么这个被打开(创建)的文件就放在哪 if (file == NULL) { printf("打开文件失败\n"); return; } Node* move = head->next; while (move != NULL) { //将结构体写入文件 if (fwrite(&move->student, sizeof(Student), 1, file) != 1) { printf("保存%s出现错误\n", move->student.name); } move = move->next; } //关闭文件 fclose(file); // 暂停程序 system("pause"); //清空控制台 system("cls");}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->student, sizeof(Student), 1, file)==1) { move->next = fresh; move = fresh;//move指针移动(始终在最后一个结点位置) fresh = malloc(sizeof(Node));//再次创捷一个新的结点fresh fresh->next = NULL; } free(fresh);//最后多定义了一个结点fresh,要把它释放掉 //关闭文件 fclose(file); printf("读取成功\n");}void modifyStudent(Node* head) { printf("请输入要修改的学生的学号:"); int stuNum; scanf("%d", &stuNum); Node* move = head->next;//将move定义在首结点(不是头结点)实现遍历 while (move != NULL) { if (stuNum == move->student.stuNum) { printf("请输入学生姓名,成绩\n"); scanf("%s%d", move->student.name,&move->student.score); printf("修改成功"); // 暂停程序 system("pause"); //清空控制台 system("cls"); return; } move = move->next; } printf("未找到学生信息"); // 暂停程序 system("pause"); //清空控制台 system("cls");}void deleteStudent(Node* head) { printf("请输入需要删除的学生学号:"); int stuNum; scanf("%d", &stuNum); Node* move = head; while (move->next!= NULL) { if (move->next->student.stuNum == stuNum) { Node* temp = move->next;//将需要删除额结点赋给临时结点,方便后面释放结点 move->next = move->next->next; free(temp);//释放掉需要删除的结点 temp = NULL;//临时结点内容被释放后,结点指针指向空 saveStudent(head);//同步文件,重新存入删除后的新链表 printf("删除成功"); // 暂停程序 system("pause"); //清空控制台 system("cls"); return; } move = move->next; } printf("未找到学生");}void sortStudent1(Node* head) { Node* move = NULL; Node* save = NULL; for (Node* turn = head->next; turn->next != NULL; turn = turn->next)//冒泡降序,控制轮数为n-1 { for (move = head->next; move->next != save; move = move->next) { if (move->student.score < move->next->student.score) { Student temp; temp = move->student; move->student = move->next->student; move->next->student = temp; } } save = move; } PrintStudent(head);//打印排序后的学生成绩}void sortStudent2(Node* head) { Node* move = NULL; Node* save = NULL; for (Node* turn = head->next; turn->next != NULL; turn = turn->next)//冒泡升序,控制轮数为n-1 { for (move = head->next; move->next != save; move = move->next) { if (move->student.stuNum > move->next->student.stuNum) { Student temp; temp = move->student; move->student = move->next->student; move->next->student = temp; } } save = move; } PrintStudent(head);//打印排序后的学生成绩}