#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME "studentinformation.txt"
#define FILECORE"core.txt"
#include <conio.h>

// 定义学生结构体
typedef struct Student {
    int id;
    char name[50];
    int age;
    struct Student* next; // 指向下一个学生节点的指针
} Student;
void saveCoreToFile(char* core)
{
    FILE* file = fopen(FILECORE,"w");
    if(file == NULL)
    {
        printf("无法打开文件保存数据!\n");
        return;
    }
    fprintf(file,"%s",core);
    fclose(file);
}
void saveToFile(Student* head) {
    FILE* file = fopen(FILENAME, "w");
    if (file == NULL) {
        printf("无法打开文件保存数据!\n");
        return;
    }
    Student* temp = head;
    while (temp != NULL) {
        fprintf(file, "%d %s %d\n", temp->id, temp->name, temp->age);
        temp = temp->next;
    }
    fclose(file);
}
// 查找学生信息
Student* findStudent(Student* head, int id) {
    Student* temp = head;
    while (temp != NULL) {
        if (temp->id == id) {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}
Student* findStudentByName(Student* head, const char* name) {
    Student* temp = head;
    while (temp != NULL) {
        if (strcmp(temp->name, name) == 0) { // 使用strcmp比较字符串
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}
// 添加学生信息到链表
Student* addStudent(Student* head, int id, const char* name, int age) {
    if (findStudent(head, id) != NULL) {
        printf("ID重复,无法添加学生信息。\n");
        return head;
    }
    Student* newStudent = (Student*)malloc(sizeof(Student));
    if (newStudent == NULL) {
        printf("内存分配失败!\n");
        return head;
    }
    newStudent->id = id;
    strcpy(newStudent->name, name);
    newStudent->age = age;
    newStudent->next = NULL;

    if (head == NULL) {
        return newStudent;
    }
    else {
        Student* temp = head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = newStudent;
    }
    return head;
}
Student* loadFromFile();





// 显示所有学生信息
void displayStudents(Student* head) {
    Student* temp = head;
    while (temp != NULL) {
        printf("ID: %d, Name: %s, Age: %d\n", temp->id, temp->name, temp->age);
        temp = temp->next;
    }
}



// 更新学生信息
void updateStudent(Student* head, int id, const char* newName, int newAge) {
    Student* student = findStudent(head, id);
    if (student != NULL) {
        strcpy(student->name, newName);
        student->age = newAge;
        printf("更新成功!\n");
    }
    else {
        printf("未找到ID为%d的学生!\n", id);
    }
}

// 删除学生信息
Student* deleteStudent(Student* head, int id) {
    Student* temp = head;
    Student* prev = NULL;

    while (temp != NULL && temp->id != id) {
        prev = temp;
        temp = temp->next;
    }

    if (temp == NULL) {
        printf("未找到ID为%d的学生!\n", id);
        return head;
    }

    if (prev == NULL) {
        head = temp->next;
    }
    else {
        prev->next = temp->next;
    }
    free(temp);
    printf("删除成功!\n");
    return head;
}

//统计平均年龄
int AverageAge(Student* head)
{
    if (head == NULL)
    {
        printf("没有学生信息,请添加学生信息\n");
        return 0;
    }
    Student* temp = head;
    int sum = 0, i = 0;
    while (temp != NULL)
    {
        i++;
        sum += temp->age;
        temp = temp->next;

    }
    return sum / i;


}
Student* InsertSortByAge(Student* head) {
      if (head == NULL) {
        printf("没有学生信息,请添加学生信息\n");
        return NULL;
    }

    Student* sorted = NULL; // 新链表,用于存储排序后的节点
    Student* current = head;

    while (current != NULL) {
        // 将当前节点从未排序链表中分离
        Student* next = current->next;

        // 查找插入位置
        if (sorted == NULL || current->age < sorted->age) {
            current->next = sorted;
            sorted = current;
        }
        else {
            Student* temp = sorted;
            while (temp->next != NULL && temp->next->age < current->age) {
                temp = temp->next;
            }
            current->next = temp->next;
            temp->next = current;
        }
        current = next;
    }

    return sorted; // 返回排序后的链表头节点
}
Student* InsertSortById(Student* head) {
    if (head == NULL) {
        printf("没有学生信息,请添加学生信息\n");
        return NULL;
    }

    Student* sorted = NULL; // 新链表,用于存储排序后的节点
    Student* current = head;

    while (current != NULL) {
        // 将当前节点从未排序链表中分离
        Student* next = current->next;

        // 查找插入位置
        if (sorted == NULL || current->id < sorted->id) {
            current->next = sorted;
            sorted = current;
        }
        else {
            Student* temp = sorted;
            while (temp->next != NULL && temp->next->id < current->id) {
                temp = temp->next;
            }
            current->next = temp->next;
            temp->next = current;
        }
        current = next;
    }
    head = sorted;
    return head; // 返回排序后的链表头节点
}
// 释放链表的内存
void freeList(Student* head) {
    Student* temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }
}
void getPassword(char* password) {
    int index = 0;
    char ch;

    while (1) {
        ch = _getch(); // 获取字符,不在控制台显示

        // 如果按下 Enter,结束输入
        if (ch == '\r') {
            password[index] = '\0'; // 结束字符串
            printf("\n"); // 换行输出
            break;
        }
        // 如果按下 Backspace,删除一个字符
        else if (ch == '\b') {
            if (index > 0) {
                printf("\b \b"); // 移回光标位置,打印空格,再移回
                index--; // 更新索引
            }
        }
        // 其他字符
        else {
                password[index++] = ch; // 存储字符
                printf("*"); // 打印星号
            }

    }
}
char* loadCoreFromFile()
{

    FILE* file = fopen(FILECORE,"r");
    if (file == NULL) {
        return NULL;
    }
char* core1 = (char*)malloc(50 * sizeof(char));
    fscanf(file,"%s",core1);
    fclose(file);
    return core1;

}
int main() {
    Student* head = NULL;
    int choice, id, age;
    char name[50];
    char core[50];
    head=loadFromFile();

    if(loadCoreFromFile()==NULL)
    {
        printf("请设置密码:");getPassword(core);

    }
    else strcpy(core,loadCoreFromFile());
    while(1)
    {
        char ans[50];
        printf("请输入密码:");getPassword(ans);
        if(!strcmp(ans,core))
        {
            saveCoreToFile(core);
            break;

        }
        else printf("密码错误\n");
        system("pause");
        system("cls");
    }

    while (1) {
        printf("\n学生管理系统\n");
        printf("1. 添加学生\n");
        printf("2. 显示所有学生\n");
        printf("3. 查找学生\n");
        printf("4. 更新学生信息\n");
        printf("5. 删除学生\n");
        printf("6.设置密码\n");
        printf("7. 退出\n");
        printf("请输入选择: ");
        scanf("%d", &choice);

        switch (choice) {
        case 1:
            printf("输入ID: ");
            scanf("%d", &id);
            printf("输入姓名: ");
            scanf("%s", name);
            printf("输入年龄: ");
            scanf("%d", &age);
            head = addStudent(head, id, name, age);
            system("cls");
            break;
        case 2:
            displayStudents(head);
            printf("学生信息管理:\n");
            printf("1.统计学生平均年龄\n");
            printf("2.按照年龄排序\n");
            printf("3.按照id排序\n");
            printf("4.退出\n");
            int choice1;
            scanf("%d", &choice1);
            switch (choice1)
            {
            case 1:
                printf("年龄平均值为:%d", AverageAge(head));
                system("pause");
                system("cls");
                break;
            case 2:head = InsertSortByAge(head);
                printf("按年龄排序完成\n");
                system("cls");
                break;
            case 3:head = InsertSortById(head);
                printf("按id排序完成\n");
                system("cls");
                break;
            case 4:system("cls");
                break;


            }
            break;
        case 3:
            printf("1.按照id查找,2.按照姓名查找\n");
            int choice2;
            scanf("%d", &choice2);
            switch (choice2)
            {
            case 2:
                printf("输入要查找的学生姓名: ");
                scanf("%s", name);
                Student* found1 = findStudentByName(head, name);
                if (found1 != NULL) {
                    printf("ID: %d, Name: %s, Age: %d\n", found1->id, found1->name, found1->age);
                }
                else {
                    printf("未找到该学生!\n");
                }
                system("pause");
                system("cls");
                break;

            case 1:
                printf("输入要查找的学生ID: ");
                scanf("%d", &id);
                Student* found = findStudent(head, id);
                if (found != NULL) {
                    printf("ID: %d, Name: %s, Age: %d\n", found->id, found->name, found->age);
                }
                else {
                    printf("未找到该学生!\n");
                }
                system("pause");
                system("cls");
                break;
            }
            break;
        case 4:
            printf("输入要更新的学生ID: ");
            scanf("%d", &id);
            printf("输入新的姓名: ");
            scanf("%s", name);
            printf("输入新的年龄: ");
            scanf("%d", &age);
            updateStudent(head, id, name, age);
            system("pause");
            system("cls");
            break;
        case 5:
            printf("输入要删除的学生ID: ");
            scanf("%d", &id);
            head = deleteStudent(head, id);
            system("pause");
            system("cls");
            break;

        case 6:
            printf("请输入密保\n");
            printf("问题:谁最爱完原神\n");
            char name1[50];
            for(int i=0;i<3;i++)
            {scanf("%s",name1);
             if(strcmp(name1,"谭子屹")!=0)
             {  if(i==2)
              {
                 saveToFile(head);
                 freeList(head);
                 saveCoreToFile(core);
                 return 0;
              }
                printf("你还有%d次机会,否则自动退出\n",2-i);
             }
             else break;
            }
            system("cls");
            while(1)
            {char tempcore1[50];
             printf("请输入新密码:");getPassword(tempcore1);
             char tempcore2[50];
             printf("请再次确认新密码:");getPassword(tempcore2);
             if(strcmp(tempcore1,tempcore2)!=0)
             {    printf("两次密码不一致,请重新输入\n");
                 continue;
             }
             else
             {
                 strcpy(core,tempcore1);
                 saveCoreToFile(core);
                 break;
             }
            }
            printf("修改密码成功\n");
            system("pause");
            system("cls");
            break;

        case 7:
            saveToFile(head);
            freeList(head);
            saveCoreToFile(core);
            printf("退出系统。\n");
            return 0;
        default:
            printf("无效选择,请重新输入!\n");
        }
    }


}
Student* loadFromFile() {
    FILE* file = fopen(FILENAME, "r");
    if (file == NULL) {
        printf("文件不存在,将创建一个新的学生列表。\n");
        return NULL;
    }

    Student* head = NULL;
    int id, age,core;
    char name[50];
    while (fscanf(file, "%d %s %d", &id, name, &age) == 3) {
        head = addStudent(head, id, name, age);
    }
    fclose(file);
    return head;
}

该系统实现了一下功能:添加学生信息,更新学生信息,删除学生信息,简单排序学生信息,查找学生等;

该项目使用了链表数据结构,并运用链表实现了插入排序算法,其中我认为最值得学习的就是密码的设置和输入及其更改;