【C语言】学生管理系统

paid星!亦舒! 2024-07-06 10:35:05 阅读 68

<code> 大家好,欢迎来到我的博客总结应用。在上一篇博客中,我写了有关结构体和内存操作函

数的总结,这些博客记录了我的学习、思考和经验。为了更好地总结和回顾这些内容,在此

篇博客中,我编写了”学生管理系统“来帮助我整理和应用上一篇博客的总结知识点。在这个

”学生管理系统“中,我列举了九条不同的标题和内容来进行说明,以下便是我的总结整理。

文章目录

一、定义学生信息的结构体二、主函数逻辑三、添加学生信息四、删除学生信息五、修改学生信息六、显示学生列表七、查询学生信息八、退出程序九、完整代码及补充

一、定义学生信息的结构体

添加必要的头文件和声明,之后定义学生信息结构体。

学生信息结构体中含有必要的学生id、学生姓名和学生成绩,除此之外,也可以自行添加一些其他信息,如学生家庭年龄,学生住址,学生班级,学生教师,学生所属学校等

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

// 学生信息结构体

typedef struct _Student {

int id;

float score; /* 数据域 */

char name[50];

struct Student *next; /* 指针域 */

} Student;

int isExistId(Student **head, int id);

void freeMemory(Student *head);

void addStudent(Student **head);

void deleteStudent(Student **head);

void updateStudent(Student **head);

void printStudent(Student **head);

void searchStudent(Student **head);

可以将数据域和指针域分开来定义,使结构逻辑更加严整。

typedef struct _Student {

int id;

float score;

char name[50];

} Student;

// 嵌套结构体

typedef struct _StuNode {

Student stu;

struct _Node *next;

} StuNode;

二、主函数逻辑

主函数主要负责输出学生管理系统的文字页面、选择对应的功能、暂停并清空控制台

int main()

{

int choice;

Student *head = NULL; // 学生链表头指针

while (1)

{

// 暂停程序

system("pause");

// 清空控制台

system("cls");

printf("--------学生管理系统--------\n");

printf("\t1. 添加学生信息\n");

printf("\t2. 删除学生信息\n");

printf("\t3. 修改学生信息\n");

printf("\t4. 显示学生列表\n");

printf("\t5. 查找学生信息\n");

printf("\t0. 退出系统\n");

printf("请选择操作:");

// 输入非数字字符,清空输入缓冲区

if (scanf("%d", &choice) != 1)

{

while (getchar() != '\n');

printf("无效的操作,请重新选择。\n");

continue;

}

// 当输入数字字符后,防止缓冲区中的字符影响自己的选择

while (getchar() != '\n');

switch (choice)

{

case 1:

addStudent(&head); // 添加学生信息

break;

case 2:

deleteStudent(&head); // 删除学生信息

break;

case 3:

updateStudent(&head); // 更新学生信息

break;

case 4:

printStudent(&head); // 打印学生信息

break;

case 5:

searchStudent(&head); // 搜索学生信息

break;

case 0:

printf("感谢使用学生管理系统,再见!\n");

freeMemory(head); // 释放内存,防止内存泄漏

exit(0);

default:

printf("无效操作,请重新选择。\n");

}

}

return 0;

}

注意,学生管理系统是需要手动退出的一个页面,所以很多操作都是在一个循环里面。

输出学生管理系统的文字页面

按照一定格式输出文字,将其美观排版后输出即可

// 文字页面

printf("--------学生管理系统--------\n");

printf("\t1. 添加学生信息\n");

printf("\t2. 删除学生信息\n");

printf("\t3. 修改学生信息\n");

printf("\t4. 显示学生列表\n");

printf("\t5. 查找学生信息\n");

printf("\t0. 退出系统\n");

printf("请选择操作:");

选择对应的功能

使用switch语句,每一种case对应一种功能,此外还需要一定的防御性编程,如选择时要求输入数字字符,消除输入数字字符的后面其他无关字符的影响

// 输入非数字字符,清空输入缓冲区

if (scanf("%d", &choice) != 1)

{

while (getchar() != '\n');

printf("无效的操作,请重新选择。\n");

continue;

}

// 当输入数字字符后,防止缓冲区中的字符影响自己的选择

while (getchar() != '\n');

switch (choice)

{

case 1:

addStudent(&head); // 添加学生信息

break;

case 2:

deleteStudent(&head); // 删除学生信息

break;

case 3:

updateStudent(&head); // 更新学生信息

break;

case 4:

printStudent(&head); // 打印学生信息

break;

case 5:

searchStudent(&head); // 搜索学生信息

break;

case 0:

printf("感谢使用学生管理系统,再见!\n");

freeMemory(head); // 释放内存,防止内存泄漏

exit(0);

default:

printf("无效操作,请重新选择。\n");

}

暂停并清空控制台

为了让输出界面和输出的结果更加直观,所以要求暂停程序观看,之后清空控制台以达到简洁直观的目的

// 暂停程序

system("pause");

// 清空控制台

system("cls");

三、添加学生信息

录入学生信息

添加学生信息这一环节主要是创建一个结点,结点中含有填写完的信息,然后把这个结点放在链表之中。

// 添加学生信息

void addStudent(Student **head) {

int id;

printf("请输入学生id: ");

scanf("%d", &id);

// 判断是否重复录取学生信息

if (IsExistId(head, id)) {

printf("已存在id为%d的学生信息!\n", id);

return;

}

// 开辟空间,并填写信息

Student *newStudent = (Student *) malloc(sizeof(Student));

newStudent->next = NULL;

char name[50];

float score;

printf("请输入学生姓名: ");

scanf("%s", name);

printf("请输入学生分数: ");

scanf("%f", &score);

newStudent->id = id;

/* 注意字符串赋值的方式 */

strcpy(newStudent->name, name);

newStudent->score = score;

// 尾插法:将结点插入在链表之后

if (*head == NULL) {

*head = newStudent;

}

else

{

Student *temp = *head;

while (temp->next != NULL) {

temp = temp->next;

}

temp->next = newStudent;

}

}

插入结点的方法

插入节点的两个方法:头插法和尾插法

头插法:将结点放在头部,使之成为新的头结点

// 头插法

// 无论有没有头结点都可以

newStudent->next = *head;

*head = newStudent;

尾插法:不断地将结点插在链表尾部

// 尾插法:将结点插入在链表之后

// 情况一,没有头结点

if (*head == NULL)

{

*head = newStudent;

}

// 情况二,有头结点

else

{

Student *temp = *head;

// 一直找到最后一个结点

while (temp->next != NULL) {

temp = temp->next;

}

temp->next = newStudent;

}

避免重复录入学生信息

为了不重复录入学生信息,定义一个IsExistId函数,该函数的实现就是遍历链表,判断链表中是否存在待录入学生的id,如果存在,返回1;否则,返回0。

int IsExistId(Student *head, int id) {

while (head != NULL) {

if (head->id == id) {

return 1;

}

}

return 0;

}

四、删除学生信息

删除学生信息

这意味着将去除链表中指定学生信息的结点,然后释放内存。

// 删除学生信息

void deleteStudent(Student **head) {

int id;

Student *temp = *head;

// 待删除结点的前一个结点,用于指向待删除结点的下一个结点

Student *prev = NULL;

printf("请输入要删除的学生id: ");

scanf("%d", &id);

// 遍历链表,查找要删除的学生结点位置

while (temp != NULL && temp->id != id) {

prev = temp;

temp = temp->next;

}

// 说明链表为空,或者到了链表尾部,即没有找到指定学生id

if (temp == NULL) {

printf("未找到学生id为%d的记录。\n", id);

return;

}

// 如果找到了要删除的学生,从链表中删除它

else

{

if (prev == NULL)

{

// 删除头节点

*head = temp->next;

}

else

{

prev->next = temp->next;

}

free(temp);

printf("已删除学生id为%d的记录。\n", id);

}

}

删除学生信息结点有两个位置区分

头结点位置:删除头结点后,头结点的下一位即为头结点其他位置:待删除结点的前一位,它的下一位是待删除结点的下一位

if (prev == NULL)

{

// 删除头节点

*head = temp->next;

}

else

{

prev->next = temp->next;

}

free(temp);

五、修改学生信息

遍历链表,找到待修改信息的学生id即可修改学生信息

// 修改学生信息

void updateStudent(Student **head)

{

int id;

Student *temp = *head;

printf("请输入要修改信息的学生id: ");

scanf("%d", &id);

while (temp != NULL && temp->id != id)

{

temp = temp->next;

}

// 要么链表为空,要么已经到链表尾部,这两种情况都是未找到id

if (temp == NULL)

{

printf("未找到学生id为%d的记录。\n", id);

}

else

{

printf("请输入新的姓名和成绩:\n");

scanf("%s %f", temp->name, &temp->score);

printf("已更新学生id为%d的信息。\n", id);

}

}

六、显示学生列表

遍历链表,将学生信息一个个打印出来。这个过程是按照链表的插入顺序进行打印输出的,还可以自己实现按照id大小排序进行输出,抑或着按照学生成绩大小排序进行输出。

// 打印学生信息

void printStudent(Student **head)

{

if (*head == NULL)

{

printf("暂未录入学生信息\n");

return;

}

printf("\n学生信息如下:\n");

Student *temp = *head;

while (temp != NULL)

{

printf("ID:%d,姓名:%s,成绩:%.2f\n", temp->id, temp->name, temp->score);

temp = temp->next;

}

}

七、查询学生信息

本质上还是遍历链表,查看是否存在指定id的人

void searchStudent(Student **head) {

int id;

Student *temp = *head;

printf("输入待搜索学生的id: ");

scanf("%d", &id);

while(temp != NULL && temp->id != id) {

temp = temp->next;

}

if (temp == NULL) {

printf("查无此id:%d信息。", id);

}

else

{

printf("id: %d name: %s score: %.2f\n", id, temp->name, temp->score);

}

}

八、退出程序

退出程序只需要在switch中添加一个选项即可,在这个选项中有exit。当然,退出程序前,要主动释放内存,避免内存泄漏。

以下这个函数也i将添加在含有exit选项中。

// 释放内存空间

void freeMemory(Student *head)

{

Student *temp;

while (head != NULL)

{

temp = head;

head = head->next;

free(temp);

}

}

九、完整代码及补充

以上就是学生管理系统的大致代码,之后若是学习了文件管理相关的函数,还可以将文件导出保存,将其他的对应格式的学生信息文件导入进行管理。除了文件管理相关的函数,我们还可以将数据导入到数据库中,这些都是之后将会学习的知识。

完整代码

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

// 学生信息结构体

typedef struct Student

{

int id;

float score; /* 数据域 */

char name[50];

struct Student *next; /* 指针域 */

} Student;

int isExistId(Student **head, int id);

void freeMemory(Student *head);

void addStudent(Student **head);

void deleteStudent(Student **head);

void updateStudent(Student **head);

void printStudent(Student **head);

void searchStudent(Student **head);

int main()

{

int choice;

Student *head = NULL; // 学生链表头指针

while (1)

{

// 暂停程序

system("pause");

// 清空控制台

system("cls");

printf("--------学生管理系统--------\n");

printf("\t1. 添加学生信息\n");

printf("\t2. 删除学生信息\n");

printf("\t3. 修改学生信息\n");

printf("\t4. 显示学生列表\n");

printf("\t5. 查找学生信息\n");

printf("\t0. 退出系统\n");

printf("请选择操作:");

// 输入非数字字符,清空输入缓冲区

if (scanf("%d", &choice) != 1)

{

while (getchar() != '\n')

;

printf("无效的操作,请重新选择。\n");

continue;

}

// 当输入数字字符后,防止缓冲区中的字符影响自己的选择

while (getchar() != '\n');

switch (choice)

{

case 1:

addStudent(&head); // 添加学生信息

break;

case 2:

deleteStudent(&head); // 删除学生信息

break;

case 3:

updateStudent(&head); // 更新学生信息

break;

case 4:

printStudent(&head); // 打印学生信息

break;

case 5:

searchStudent(&head); // 搜索学生信息

break;

case 0:

printf("感谢使用学生管理系统,再见!\n");

freeMemory(head); // 释放内存,防止内存泄漏

exit(0);

default:

printf("无效操作,请重新选择。\n");

}

}

return 0;

}

// 添加学生信息

void addStudent(Student **head)

{

int id;

printf("请输入学生id: ");

scanf("%d", &id);

// 判断是否重复录取学生信息

if (isExistId(head, id))

{

printf("已存在id为%d的学生信息!\n", id);

return;

}

// 开辟空间,并填写信息

Student *newStudent = (Student *)malloc(sizeof(Student));

newStudent->next = NULL;

char name[50];

float score;

printf("请输入学生姓名: ");

scanf("%s", name);

printf("请输入学生分数: ");

scanf("%f", &score);

newStudent->id = id;

/* 注意字符串赋值的方式 */

strcpy(newStudent->name, name);

newStudent->score = score;

// 尾插法:将结点插入在链表之后

if (*head == NULL)

{

*head = newStudent;

}

else

{

Student *temp = *head;

while (temp->next != NULL)

{

temp = temp->next;

}

temp->next = newStudent;

}

}

// 删除学生信息

void deleteStudent(Student **head)

{

int id;

Student *temp = *head;

// 待删除结点的前一个结点,用于指向待删除结点的下一个结点

Student *prev = NULL;

printf("请输入要删除的学生id: ");

scanf("%d", &id);

// 遍历链表,查找要删除的学生结点位置

while (temp != NULL && temp->id != id)

{

prev = temp;

temp = temp->next;

}

// 如果找到了要删除的学生,从链表中删除它

if (temp == NULL)

{

printf("未找到学生id为%d的记录。\n", id);

return;

}

else

{

if (prev == NULL)

{

// 删除头节点

*head = temp->next;

}

else

{

prev->next = temp->next;

}

free(temp);

printf("已删除学生id为%d的记录。\n", id);

}

}

// 修改学生信息

void updateStudent(Student **head)

{

int id;

Student *temp = *head;

printf("请输入要修改信息的学生id: ");

scanf("%d", &id);

while (temp != NULL && temp->id != id)

{

temp = temp->next;

}

// 要么链表为空,要么已经到链表尾部,这两种情况都是未找到id

if (temp == NULL)

{

printf("未找到学生id为%d的记录。\n", id);

}

else

{

printf("请输入新的姓名和成绩:\n");

scanf("%s %f", temp->name, &temp->score);

printf("已更新学生id为%d的信息。\n", id);

}

}

// 打印学生信息

void printStudent(Student **head)

{

if (*head == NULL)

{

printf("暂未录入学生信息\n");

return;

}

printf("\n学生信息如下:\n");

Student *temp = *head;

while (temp != NULL)

{

printf("ID: %d\t 姓名: %s\t 成绩: %.2f\n", temp->id, temp->name, temp->score);

temp = temp->next;

}

}

// 释放内存空间

void freeMemory(Student *head)

{

Student *temp;

while (head != NULL)

{

temp = head;

head = head->next;

free(temp);

}

}

// 判断链表中是否存在指定学生id

int isExistId(Student **head, int id)

{

Student *temp = *head;

while (temp != NULL)

{

if (temp->id == id)

{

return 1;

}

temp = temp->next;

}

return 0;

}

void searchStudent(Student **head) {

int id;

Student *temp = *head;

printf("输入待搜索学生的id: ");

scanf("%d", &id);

while(temp != NULL && temp->id != id) {

temp = temp->next;

}

if (temp == NULL) {

printf("查无此id:%d信息。\n", id);

}

else

{

printf("id: %d name: %s score: %.2f\n", id, temp->name, temp->score);

}

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。