使用C语言,链表完成的简单宿舍管理系统
有一定bug,至今无法解决
main函数
遍历每个房东(从0到MAX_LANDLORDS-1)
要求管理员输入账号和密码,直到输入正确为止。
调用 createDormitoryList() 函数创建包含所有寝室的链表。
调用 loadFromFile() 函数从文件中加载学生信息。
显示菜单,让管理员选择要执行的功能。
根据管理员选择的功能,调用相应的函数模块执行相应的操作,如添加学生、查询学生、学生寝室调换等。
每次管理员选择完功能后,调用 saveToFile() 函数将学生信息保存到文件中。
程序执行完管理员选择的功能后,检查是否选择退出程序功能,如果是则退出程序,否则继续显示菜单供管理员选择。
createDormitoryList() 函数:
创建头节点,并分配内存。
使用循环创建50个寝室节点,并为每个节点分配内存。
初始化寝室节点的寝室号、学生数量和 next 指针。
返回头节点指针,作为整个寝室链表的起始点。
loadFromFile() 函数:
打开名为 "students.txt" 的文本文件,以读取模式打开。
使用循环读取文件中的每一行,每行包含一个学生的姓名、学号和寝室号。
调用 addStudent() 函数将读取的学生信息添加到寝室链表中。
关闭文件。
addStudent() 函数:
接收输入的学生姓名、学号和目标寝室号。
遍历寝室链表,找到目标寝室。
如果寝室未满,将学生信息添加到该寝室。
如果寝室已满,输出提示信息。
saveToFile() 函数:
打开名为 "students.txt" 的文本文件,以写入模式打开。
遍历寝室链表,将每个寝室中的学生信息写入文件,每个学生的姓名、学号和寝室号写在一行中,之间用空格分隔。关闭文件。
findStudent() 函数:
接收输入的学生学号。
遍历寝室链表,在每个寝室中查找匹配的学生学号。
如果找到匹配的学生,输出学生的姓名、学号和所在寝室号。
如果未找到匹配的学生,输出提示信息。
changeDormitory() 函数:
接收输入的学生学号和新的寝室号。
遍历寝室链表,在每个寝室中查找匹配的学生学号。
如果找到匹配的学生,将学生从原来的寝室中移除,并添加到新的寝室中。
如果未找到匹配的学生,输出提示信息。
printDormitories() 函数:
遍历寝室链表,对于每个寝室,输出寝室号。
遍历当前寝室中的学生数组,对于每个学生,输出其姓名和学号。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STUDENTS 4
typedef struct Student {//学生结构体
char name[50];
char id[13];
} Student;
typedef struct Dormitory {//寝室结构体
int dormitoryNumber;//寝室编号
Student students[MAX_STUDENTS]; //结构体数组 ,四人寝
int studentCount;//寝室人数计数
struct Dormitory* next;//指向下一节点
} Dormitory;
void getInput(char* name, char* id, int* dormitory) {//输入限制函数
printf("请输入学生姓名:");
scanf("%s", name);
printf("请输入学生学号:");
scanf("%s", id);
while (strlen(id) != 13) {
printf("学号长度不正确,请重新输入:");
scanf("%s", id);
}
printf("请输入寝室号:");
scanf("%d", dormitory);
while (*dormitory < 1 || *dormitory > 50) {
printf("寝室号不正确,请重新输入:");
scanf("%d", dormitory);
}
}
void addStudent(Dormitory* head, char* name, char* id, int dormitoryNumber) {//学生添加函数
Dormitory* current = head->next;
while (current != NULL) {
if (current->dormitoryNumber == dormitoryNumber) {//找到目标寝室
if (current->studentCount < MAX_STUDENTS) {//判断寝室是否住满
strcpy(current->students[current->studentCount].name, name);//字符串前面复制到后面 current指向每个节点数组的 count个
strcpy(current->students[current->studentCount].id, id);
current->studentCount++;
} else {
printf("寝室已满!\n");
}
break;
}
current = current->next;//指向下一个节点
}
}
void saveToFile(Dormitory* head) {//学生信息保存到文件
FILE* file = fopen("students.txt", "w");
Dormitory* current = head->next;//创建一个指向链表的第一个节点的指针。
while (current != NULL) {
for (int i = 0; i < current->studentCount; i++) {
fprintf(file, "%s %s %d\n", current->students[i].name, current->students[i].id, current->dormitoryNumber);
}//将当前学生的姓名、学号和寝室号写入到文件中。每个学生的信息都会写在一行中,姓名、学号和寝室号之间用空格分隔
current = current->next;//指向下一个节点
}
fclose(file);
}
void loadFromFile(Dormitory* head) {//从文件加载学生信息
FILE* file = fopen("students.txt", "r");//打开文件students。txt,读取模式 ,打开成功则返回指针
if (file == NULL) {
printf("无法打开文件!\n");
return;
}
char name[50];
char id[13];
int dormitory;
while (fscanf(file, "%s %s %d", name, id, &dormitory) == 3) {//成功读取3个值返回3
addStudent(head, name, id, dormitory);
}
fclose(file);//关闭文件
}
Dormitory* createDormitoryList() {//创造所有寝室
Dormitory* head = (Dormitory*)malloc(sizeof(Dormitory));
head->next = NULL;//创建一头指针
for (int i = 1; i <= 50; i++) {
Dormitory* newDormitory = (Dormitory*)malloc(sizeof(Dormitory));//创造寝室节点
newDormitory->dormitoryNumber = i;
newDormitory->studentCount = 0;
newDormitory->next = head->next;
head->next = newDormitory;
}
return head;
}
void findStudent(Dormitory* head, char* id) {//学生查询功能
Dormitory* current = head->next;
while (current != NULL) {
for (int i = 0; i < current->studentCount; i++) {
if (strcmp(current->students[i].id, id) == 0) {
printf("姓名:%s 学号:%s 寝室号:%d\n", current->students[i].name, current->students[i].id, current->dormitoryNumber);
return;
}
}
current = current->next;
}
printf("未找到该学生!\n");
}
void changeDormitory(Dormitory* head, char* id, int newDormitoryNumber) {//寝室调换功能
Dormitory* current = head->next;
Student student;
int found = 0;
while (current != NULL) {
for (int i = 0; i < current->studentCount; i++) {
if (strcmp(current->students[i].id, id) == 0) {
student = current->students[i];
current->students[i] = current->students[current->studentCount - 1];
current->studentCount--;
found = 1;
break;
}
}
if (found) {
break;
}
current = current->next;
}
if (found) {
addStudent(head, student.name, student.id, newDormitoryNumber);
} else {
printf("未找到该学生!\n");
}
}
void printDormitories(Dormitory* head) {//打印所有寝室
Dormitory* current = head->next;//结构体指针指向第一个节点 寝室号为50
while (current != NULL) {
printf("寝室号:%d\n", current->dormitoryNumber);
for (int i = 0; i < current->studentCount; i++) {
printf("姓名:%s 学号:%s\n", current->students[i].name, current->students[i].id);
}
current = current->next;
}
}
int main() {
int admin_id, admin_password;
printf("请输入管理员账号和密码:\n");
while(1){
scanf("%d %d", &admin_id, &admin_password);
if (admin_id == 1 && admin_password == 1) {
break;
}
printf("账号或密码错误,请重新输入\n");
}
printf("——登陆成功——\n");
Dormitory* head = createDormitoryList();//创建寝室链表
loadFromFile(head);//从文件中加载学生信息
while (1) {
printf("请选择功能:1.添加学生 2.学生查询 3.学生寝室调换 4.汇总\n");
int choice;
scanf("%d", &choice);
if (choice == 1) {
char name[50];
char id[13];
int dormitory;
getInput(name, id, &dormitory);//输入限制
addStudent(head, name, id, dormitory);//添加学生到节点
} else if (choice == 2) {
char id[13];
printf("请输入学生学号:");
scanf("%s", id);
findStudent(head, id);
} else if (choice == 3) {
char id[13];
int newDormitory;
printf("请输入学生学号:");
scanf("%s", id);
printf("请输入新的寝室号:");
scanf("%d", &newDormitory);
changeDormitory(head, id, newDormitory);
} else if (choice == 4) {
printDormitories(head);//嫌疑
} else {
break;
}
saveToFile(head);//将链表中学生信息保存到文件
}
return 0;
}