本代码比较完善,有登录模块和菜单模块,拥有很高的可操控性和可观性。
代码所包含的功能有很多:成绩输入与删除,按位置查询学生,按姓名查找学生,求表的长度,求最高分学生信息,显示全部学生信息,保存与读取文件......
本代码的文件读取和文件保存是一大亮点,可以灵活的存取,启动一次可以切换文档读写,我也对其进行了详细的注释。
以下是全部的代码:(记得点个赞和关注支持一下哦 ~)
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "conio.h"
// 定义学生结构体
typedef struct student {
long long int id;
char name[50];
float score;
struct student *next;
} Student;
// 函数声明
Student* createList();
void insertStudent(Student** head);
void deleteStudent(Student** head);
Student* findStudentByPosition(Student* head, int position);
Student* findStudentByName(Student* head, char* name);
int listLength(Student* head);
Student* findHighestScoreStudent(Student* head);
void saveListToFile(Student* head, char* filename);
Student* readListFromFile(char* filename);
void displayStudent(Student* s);
void displayAllStudents(Student* head);
void home();
int main(){
printf("\n\n");
printf(" \t┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf(" \t┃******************************************┃\n");
printf(" \t┃*** ****┃\n");
printf(" \t┃*** 欢迎使用班级成绩管理系统 ****┃\n");
printf(" \t┃*** ****┃\n");
printf(" \t┃*** 宁夏大学新华学院 ****┃\n");
printf(" \t┃*** ****┃\n");
printf(" \t┃*** 指导老师:XXXXXX ****┃\n");
printf(" \t┃*** ****┃\n");
printf(" \t┃*** 操作学生:XXXXXX ****┃\n");
printf(" \t┃*** ****┃\n");
printf(" \t┃******************************************┃\n");
printf(" \t┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
char userName[20] , pwd[10];
int flag = 1;
for(int i=0; i<3; i++){
printf("请输入用户名:");
//读用户名数据
//scanf("%s" , &userName);同学的
scanf("%s" , userName);//老师
printf("userName = %s \n\n" , userName);
printf("请输入密码:");
//自己写
scanf("%s" , pwd); //读入密码存放到pwd数组中
printf("pwd = %s \n\n" , pwd);
//验证jia 666
//userName = jia
//strcmp
int a = strcmp(userName , "jia"); //整数值 头string.h -1 0
printf("a = %d \n" , a);
int b = strcmp(pwd , "666");
printf("b = %d \n" , b);
if(a==0 && b==0){
printf("==登录成功==\n");
flag = 0;//0成功 1没成功
//............
for(int j=0; j<20; j++){
printf(".");
Sleep(100);//window.h
}
home();
break;//跳出for
}else{
printf("用户名或密码错误,请重新输入\n\n");
}
}
//没成功
if(flag==1){//1 0
printf("3次登录失败,系统退出\n\n");
exit(0);//退出系统
}
}
void menu() /*进入菜单*/
{
system("cls");
printf("\n");
printf("\n");
printf("┃******欢迎进入学生成绩管理系统(链表)******┃\n");
printf("┃ 菜单 ┃\n");
printf("┃ 1、成绩输入 ┃\n");
printf("┃ 2、成绩删除 ┃\n");
printf("┃ 3、按位置查询学生 ┃\n");
printf("┃ 4、按姓名查找学生 ┃\n");
printf("┃ 5、求表的长度 ┃\n");
printf("┃ 6、求最高分学生信息 ┃\n");
printf("┃ 7、显示全部学生信息 ┃\n");
printf("┃ 8、保存文件 ┃\n");
printf("┃ 9、读取文件 ┃\n");
printf("┃ 0、退出系统 ┃\n");
printf("┃********请选择相应的功能号(0---9):*******┃\n");
}
//
void home() /*功能选项调用*/
{
int mm=0;
menu();
Student* head = createList();
char choice;
do
{
mm=1;
fflush(stdin);
switch(getchar())//#include "conio.h "
{
case '1' :{insertStudent(&head);break;} /*成绩输入*/
case '2' :{deleteStudent(&head);break;} /*成绩删除*/
case '3' : {int position;
printf("输入要查找的位置:");
scanf("%d", &position);
displayStudent(findStudentByPosition(head, position));break;} /*按位置查询学生*/
case '4' : {char name[50];
printf("输入要查找的学生姓名:");
scanf("%s", name);
displayStudent(findStudentByName(head, name));break;} /*按姓名查找学生*/
case '5' : {printf("表长为:%d\n", listLength(head));break;} /*求表的长度*/
case '6' : {displayStudent(findHighestScoreStudent(head));break;} /*求最高分学生信息*/
case '7' : {displayAllStudents(head);break;} /*显示全部学生信息*/
case '8' : {char filename[100];
printf("输入要保存的文件名:");
scanf("%s", filename);
saveListToFile(head, filename);break;} /*成绩保存*/
case '9' : {char filename[100];
printf("输入要读取的文件名:");
scanf("%s", filename);
Student* newHead = readListFromFile(filename);
if (newHead!= NULL) {
head = newHead;
}break;} /*成绩读取*/
case '0' : {exit(0);} /*退出程序*/
default : printf("输入有误\n");
}
printf("按任意键继续\n");
getch();//getch()是编程中所用的函数,这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车
menu();
}while (mm==1);
Student* current = head;
while (current!= NULL) {
Student* next = current->next;
free(current);
current = next;
}
}
// 创建链表
Student* createList() {
return NULL;
}
// 插入学生
void insertStudent(Student** head) {
system("cls");
puts("========录入成绩=======");
Student* newStudent = (Student*)malloc(sizeof(Student));
printf("输入学生 ID:");
scanf("%d", &newStudent->id);
printf("输入学生姓名:");
scanf("%s", newStudent->name);
printf("输入学生成绩:");
scanf("%f", &newStudent->score);
newStudent->next = NULL;
if (*head == NULL) {
*head = newStudent;
} else {
Student* current = *head;
while (current->next!= NULL) {
current = current->next;
}
current->next = newStudent;
}
}
// 删除学生
void deleteStudent(Student** head) {
system("cls");
puts("========删除成绩=======");
long long int id;
printf("输入要删除的学生 ID:");
scanf("%lld", &id);
Student* current = *head;
Student* prev = NULL;
while (current!= NULL) {
if (current->id == id) {
if (prev == NULL) {
*head = current->next;
} else {
prev->next = current->next;
}
free(current);
printf("学生信息已删除。\n");
return;
}
prev = current;
current = current->next;
}
printf("未找到该学生。\n");
}
// 按位置查找学生
Student* findStudentByPosition(Student* head, int position) {
system("cls");
puts("========按位置查找学生=======");
Student* current = head;
int count = 1;
while (current!= NULL && count < position) {
current = current->next;
count++;
}
if (current!= NULL && count == position) {
return current;
} else {
return NULL;
}
}
// 按姓名查找学生
Student* findStudentByName(Student* head, char* name) {
system("cls");
puts("========按姓名查找学生=======");
Student* current = head;
while (current!= NULL) {
if (strcmp(current->name, name) == 0) {
return current;
}
current = current->next;
}
return NULL;
}
// 求表长
int listLength(Student* head) {
system("cls");
puts("========求表长=======");
int length = 0;
Student* current = head;
while (current!= NULL) {
length++;
current = current->next;
}
return length;
}
// 求链表中成绩最高分的学生信息
Student* findHighestScoreStudent(Student* head) {
system("cls");
puts("========求最高分=======");
Student* highestScoreStudent = head;
Student* current = head->next;
while (current!= NULL){
if (current->score>highestScoreStudent->score){
highestScoreStudent = current;
}
current = current->next;
}
return highestScoreStudent;
}
// 保存文件
void saveListToFile(Student* head, char* filename) {
// 清屏操作,使输出界面更清晰
system("cls");
// 输出提示信息,表示正在保存成绩
puts("========保存成绩=======");
// 尝试以只写模式打开指定文件名的文件,如果文件不存在则创建新文件
FILE* file = fopen(filename, "w");
// 如果文件打开失败
if (file == NULL) {
// 输出错误信息,提示无法打开文件进行写入
printf("无法打开文件进行写入。\n");
// 直接返回,结束函数
return;
}
// 定义一个指针 current,用于遍历链表,初始指向链表头节点
Student* current = head;
// 当 current 不为空时,即还未遍历完链表
while (current!= NULL) {
// 将当前节点的学生信息(学号、姓名、成绩)按照指定格式写入文件
fprintf(file, "%d %s %.2f\n", current->id, current->name, current->score);
// 将 current 指针指向下一个节点,继续遍历
current = current->next;
}
// 关闭文件
fclose(file);
// 输出提示信息,表示文件保存成功
puts("文件保存成功!");
}
// 读取文件
Student* readListFromFile(char* filename) {
// 清屏操作,使输出界面更清晰
system("cls");
// 输出提示信息,表示正在读取成绩
puts("========读取成绩=======");
// 尝试以只读模式打开指定文件名的文件
FILE* file = fopen(filename, "r");
// 如果文件打开失败
if (file == NULL) {
// 输出错误信息,提示无法打开文件进行读取
printf("无法打开文件进行读取。\n");
// 返回空指针,表示读取失败
return NULL;
}
// 定义链表头指针,初始化为空,表示链表为空
Student* head = NULL;
// 定义链表尾指针,初始化为空,表示链表为空
Student* tail = NULL;
// 定义用于存储学生学号的变量
long long int id;
// 定义用于存储学生姓名的字符数组
char name[50];
// 定义用于存储学生成绩的变量
float score;
// 当从文件中读取数据且未到文件末尾时循环
while (fscanf(file, "%lld %s %f", &id, name, &score)!= EOF) {
// 动态分配内存,创建一个新的学生节点
Student* newStudent = (Student*)malloc(sizeof(Student));
// 将读取到的学号赋值给新节点的 id 成员
newStudent->id = id;
// 将读取到的姓名复制到新节点的 name 成员
strcpy(newStudent->name, name);
// 将读取到的成绩赋值给新节点的 score 成员
newStudent->score = score;
// 将新节点的 next 指针置为空,表示当前新节点为链表的最后一个节点
newStudent->next = NULL;
// 如果链表为空(头指针为 NULL)
if (head == NULL) {
// 将新节点设置为链表的头节点
head = newStudent;
// 将新节点也设置为链表的尾节点
tail = newStudent;
} else {
// 如果链表不为空,将新节点连接到链表末尾
tail->next = newStudent;
// 更新尾指针,使其指向新的尾节点
tail = newStudent;
}
}
// 关闭文件
fclose(file);
// 输出提示信息,表示文件读取成功
puts("文件读取成功!");
// 返回链表的头指针
return head;
}
// 显示学生信息
void displayStudent(Student* s) {
if (s!= NULL) {
printf("ID: %lld, 姓名: %s, 成绩: %.2f\n", s->id, s->name, s->score);
} else {
printf("未找到学生。\n");
}
}
//显示全部学生信息
void displayAllStudents(Student* head) {
system("cls");
puts("========全部学生信息=======");
Student* current = head;
if (current == NULL) {
printf("链表中没有学生信息。\n");
return;
}
printf("学生信息如下:\n");
while (current!= NULL) {
displayStudent(current);
current = current->next;
}
}
运行结果:
以下的所有功能都可以很好的实现,记得三连我哦~
标签:current,head,NULL,管理系统,next,链表,Student,printf,数据结构 From: https://blog.csdn.net/qq_49964423/article/details/143222492