实训项目:学生信息管理系统

采用的双向循环列表

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
//用链表来实现这个代码 //双向循环列表

typedef struct student
{
   
    int Numb;   //学号
    char Name[10];  //姓名
    int Score[3];   //三科平均成绩
    double Ave;     // 平均成绩

}STU;

typedef struct LTNode
{
    STU stu;                    
    struct LTNode* prev;
    struct LTNode* next;

}LTNode;


//这是目录
void menu()
{

    printf("       \033[0m\033[1;31m  ***学生成绩管理系统********* \033[0m             \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("         ***10.备份								   \n");
    printf("         ***11.修改密码							   \n");
    printf("         ***12.选出不及格							   \n");
    printf("         *** 0.退出系统		 				    	\n");
    printf("         ****************************************** \n");
}


void _UN_pass(LTNode*phead,const int Case)
{
    int numb = 0;
    LTNode* current = phead->next;
    printf("以下等人在你选的科目中不及格\n");
    printf("学号\t姓名\t语文\t数学\t英语\t平均分\n");

    while (current != phead)
    {
        if (current->stu.Score[Case-1] < 60)
        {
            numb++;
            printf("%d\t%s\t%d\t%d\t%d\t%f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2], current->stu.Ave);
        }
        current = current->next;
    }
    printf("一共有%d个人不及格\n",numb);
}

void Find_UN_pass(LTNode* phead)
{
    if (phead->next == NULL)
    {
        printf("无数据,即将返回!\n");
        return;
    }
    printf("请问你想查询某科成绩不合格的人\n");
    printf("\t1.语文\t2.数学\t3.外语\t4.平均成绩\n");
    int choice = 0;
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:_UN_pass(phead,choice); break;
    case 2:_UN_pass(phead, choice); break;

    case 3:_UN_pass(phead, choice); break; 
    case 4:_UN_pass(phead, choice); break;

    default:    printf("输入错误!\n");
        break;
    }

}

//定义一个哨兵位,并对其赋值为空
LTNode* Init()
{
    LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
    if (phead == NULL)
    {
        //如果没有申请成功,就报错
        exit(-1);
    }
    phead->next = NULL;
    phead->prev = NULL;
    return phead;
}

//创造一个新的节点,并向其中输入数据
LTNode* BuyLTN(STU student)
{
    //首先申请一个空间
    LTNode* NewNode = (LTNode*)malloc(sizeof(LTNode));
    //判断是否成功申请
    if (NewNode == NULL)
    {
        exit(-1);
    }
    //对节点进行赋值
    NewNode->next = NULL;
    NewNode->prev =NULL;
    NewNode->stu.Numb =student.Numb ;
    strcpy(NewNode->stu.Name, student.Name);
    for (int i = 0; i < 3; i++)
    {
        NewNode->stu.Score[i] = student.Score[i];
    }
    NewNode->stu.Ave = student.Ave;
    return NewNode;
}

//输入学生的信息
void AddStudent(LTNode** phead)
{
   
    printf("请输入你需要输入多少个人的信息\n");
    int Num_STU = 0;                     
    scanf("%d", &Num_STU);

    LTNode* current =*phead; // 指向头节点  
    LTNode* tail = *phead;    // 用于指向链表的末尾节点 

    for (int i = 0; i < Num_STU; i++)
    {
        STU student;

        printf("学号\t姓名\t语文\t数学\t英语\n");
        scanf("%d", &student.Numb); 
        scanf("%s", student.Name); 
        scanf("%d", &student.Score[0]); 
        scanf("%d", &student.Score[1]); 
        scanf("%d", &student.Score[2]);
        student.Ave = (student.Score[0] + student.Score[1] + student.Score[2]) / 3.0;

        LTNode* newNode = BuyLTN(student);

        if (current->next == NULL)
        {
            // 如果链表为空,添加第一个节点  
            current->next = newNode;
            newNode->prev = current;
            newNode->next = current; // 因为是循环链表,新节点的next指向头节点  
            current->prev = newNode; // 更新头节点的prev指向新节点  
            tail = newNode; // 更新尾节点  
        }
        else
        {
            // 链表非空,添加新节点到末尾
            tail->next = newNode;
            newNode->prev = tail;
            newNode->next = current; // 新节点的next指向头节点  
            current->prev = newNode; // 更新头节点的prev指向新节点  
            tail = newNode; // 更新尾节点  
        }
    }
    
}

//输出学生的信息
void showStudent(LTNode*head)
{
    
    if (head->next == NULL)
    {
        printf("Empty !!\n");
    }
    else
    {
        LTNode* current = head->next;
        while (current != head)
        {
            printf("学号\t姓名\t语文\t数学\t英语\t平均分\n");
            printf("%d\t%s\t%d\t%d\t%d\t%f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2],current->stu.Ave);
            current = current->next;
        }
    }
}


//通过姓名进行寻找
void searchByName(LTNode* phead)
{
    char name[10];
    printf("请输入你需要查找的姓名\n");
    scanf("%s", name);
    LTNode* current = phead->next;
    while (current != phead)
    {
        if (strcmp(current->stu.Name, name) == 0)
        {
            break;
        }
        current = current->next;
    }
    printf("%d\t%s\t%d\t%d\t%d\t%.2f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2], current->stu.Ave);
    
}


//通过学号进行寻找
void searchByNumb(LTNode* phead)
{
    int num = 0;
    if (phead->next == NULL)
    {
        printf("人数为 0");
        return ;
    }
    printf("请输入你要查找的学号\n");
    scanf("%d", &num);
    LTNode* current = phead->next;
    while (current != phead)
    {
        if (current->stu.Numb == num)
        {
            break;
        }
        current = current->next;
    }
    if (current == phead)
    {
        printf("  \033[0m\033[1;31m 没有你搜寻的人!!   \033[0m \n");
        return ;
    }
    printf("%d\t%s\t%d\t%d\t%d\t%.2f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2], current->stu.Ave);

}


//搜索学生信息
void search(LTNode* phead)
{
   //首先需要确定是根据学号进行搜索还是根据名字进行搜索
    printf("欢迎进入搜索功能,根据学号搜索请输入 0 ,根据姓名搜索请输入  1  \n");
    int choice = 0;                 //默认使用学号搜索
    scanf("%d", &choice);
    switch (choice)
    {
    case 0:       searchByNumb(phead);              break;  //使用学号进行搜索

    case 1:       searchByName(phead);                break;  //使用姓名进行搜索
    }

}

// 插入学生的位置
void insert(LTNode**phead)   
{
    int place = 0;
    printf("请输入你要插入的位置\n");
    scanf("%d", &place);
    LTNode* current = *phead;

    //通过循环current指定到要插入的位置
    for (int i = 0; i < place-1; i++)
    {
        current = current->next;
    }
    printf("请输入你需要插入的学生的信息\n");
    STU student;

    printf("学号\t姓名\t语文\t数学\t英语\n");
    scanf("%d", &student.Numb);
    scanf("%s", student.Name);
    scanf("%d", &student.Score[0]);
    scanf("%d", &student.Score[1]);
    scanf("%d", &student.Score[2]);
    student.Ave = (student.Score[0] + student.Score[1] + student.Score[2]) / 3.0;
    LTNode* newNode = BuyLTN(student);
    LTNode* next = current->next;
    current->next = newNode;
    newNode->prev = current;
    newNode->next = next;
    next->prev = newNode;
}

//通过名字进行删除
 void DeleteByname(LTNode *phead)
{
     char name[10];
     printf("请输入你要删除的名字\n");
     scanf("%s", name);
     LTNode* current=phead;
     LTNode* head = phead;
     LTNode* prev = NULL;
     // 遍历链表查找要删除的节点  
     while (current->next != head)
     {
         if (strcmp(current->stu.Name, name)==0)
         {
             current->prev->next = current->next;
             current->next->prev = current->prev;
             free(current);
             current = NULL;
             printf("删除成功!");
             return;
         }
         current = current->next;

     }
     printf("删除失败:未找到名为 %s 的学生\n", name);
     printf("接下来将会回到主面板\n");
 }


 //通过学号进行删除
 void DeleteBynumb(LTNode*phead)
 {
     int numb = 0;
     printf("请输入你要删除的学号\n");
     scanf("%d", &numb);
     LTNode* current = phead;
     while (current->next !=phead )
     {
         //当没有便利链表的时候就会一直在循环中执行
         if (current->stu.Numb == numb)
         {
             current->prev->next = current->next;
             current->next->prev = current->prev;
             free(current);
             current = NULL;
             printf("删除成功");
             return;
         }
         current = current->next;
     }
     printf("删除失败,未找到学号为%d的学生\n", numb);
     printf("接下来将会回到主面板\n");
 }


//删除学生信息
void Delete(LTNode* phead)
{
    printf("请问你要通过学号进行删除还是通过名字进行删除 \n");
    printf("通过学号请按 0\t 通过姓名请按  1\n");
    int choice = 0;
    scanf("%d", &choice);
    switch (choice)
    {
    case 0:DeleteBynumb(phead);          break;
    case 1: DeleteByname(phead);         break;
    default: printf("输入错误!");        break;
    }
}



//这是update的具体操作

 void updata(LTNode * current) 
 {
        printf("能够更新的有以下几种数据:\n");
        printf("\n1. 学号\n2. 姓名\n3. 语文\n4. 数学\n5. 英语\n"); 
        printf("请问你需要更新几种数据?  \n");
        int times;
        scanf("%d", &times);

        for (int i = 0; i < times; i++)
        {
            int choice;
            printf("请选择要更新的项目:");
            scanf("%d", &choice);
            switch (choice)
            {
            case 1:
                printf("请输入新的学号:"); scanf("%d", &current->stu.Numb); break;
            case 2:
                printf("请输入新的姓名:"); scanf("%s", current->stu.Name); break;
            case 3:
                printf("请输入新的语文成绩:"); scanf("%d", &current->stu.Score[0]); break;
            case 4:
                printf("请输入新的数学成绩:"); scanf("%d", &current->stu.Score[1]);  break;
            case 5:
                printf("请输入新的英语成绩:"); scanf("%d", &current->stu.Score[2]); break;
            default:
                printf("输入错误,请重新输入。\n");    i--; // 输入错误时,不增加循环计数  
                break;
            }
        }
        current->stu.Ave = (current->stu.Score[0] + current->stu.Score[1] + current->stu.Score[2])/3.0;
        printf("以下是更新之后的数据:\n");
        printf("%d\t%s\t%d\t%d\t%d\t%f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2],current->stu.Ave);
    }


//通过学号来更改
void UpdataBynumb(LTNode* phead)
{
    printf("请输入你需要需要更新信息学生的学号\n");
    int numb = 0;
    scanf("%d", &numb);
   
    LTNode *current = phead;
    while (current->next != phead)
    {
        if (current->stu.Numb == numb)
        {
            printf("以下是你即将修改的学生的信息\n");
            printf("学号\t姓名\t语文\t数学\t英语\n");
            printf("%d\t%s\t%d\t%d\t%d\t%f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2], current->stu.Ave);
            updata(current);
            return;
        }
        current = current->next;
    }
    printf("更新失败,请重试\n");
}


//通过姓名进行更改
void UpdataByname(LTNode* phead)
{
    printf("请输入你需要需要更新信息学生的姓名\n");
    char name[10];
    scanf("%s", name);

    LTNode* current = phead;
    
    while (current->next != phead)
    {
        if (strcmp(current->stu.Name,name) == 0)
        {
            printf("以下是你即将修改的学生的信息\n");
            printf("学号\t姓名\t语文\t数学\t英语\n");
            printf("%d\t%s\t%d\t%d\t%d\t%f\n", current->stu.Numb, current->stu.Name, current->stu.Score[0], current->stu.Score[1], current->stu.Score[2], current->stu.Ave);
            updata(current);
            return;
        }
        current = current->next;
    }
    printf("更新失败,请重试\n");
}



//更新学生的信息
void Updata(LTNode* phead)
{
    printf("现在进行的是修改学生的个人信息  \n");
    printf("请问你是要通过 学号(选0) 进行修改还是通过 名字(选1) 找到你需要的学生\n");
    int choice = 0;  //默认通过学号进行输入
    scanf("%d", &choice);
    switch (choice)
    {
    case 0:     UpdataBynumb(phead);     break;
    case 1:     UpdataByname(phead);     break;
    default:break;
    }
}

//排序操作  升序
void swap(LTNode* current)
{
    STU mid;
    mid.Ave = current->stu.Ave;
    strcpy(mid.Name, current->stu.Name);

    for (int i = 0; i < 3; i++)
    {
        mid.Score[i] = current->stu.Score[i];
    }
    mid.Numb = current->stu.Numb;


    current->stu.Ave = current->next->stu.Ave;
    current->stu.Numb = current->next->stu.Numb;
    for (int i = 0; i < 3; i++)
    {
        current->stu.Score[i] = current->next->stu.Score[i];
    }
    strcpy(current->stu.Name, current->next->stu.Name);

    current->next->stu.Ave = mid.Ave;
    current->next->stu.Numb = mid.Numb;
    for (int i = 0; i < 3; i++)
    {
        current->next->stu.Score[i] = mid.Score[i];
    }
    strcpy(current->next->stu.Name, mid.Name);
}



void sort_By_English(LTNode* phead)
{
    if (phead == NULL || phead->next == phead)
    {
        return; // 空链表或只有一个节点,无需排序  
    }
    int swapped;
    LTNode* tail = phead->prev;
    do
    {
        LTNode* current = phead->next;
        swapped = 0;
   
        while (current != tail)
        {
            LTNode* next = current;
            next = current->next;
            if (current->stu.Score[2] > next->stu.Score[2])
            {
                swap(current);
                swapped = 1;
            }
            current = next;
        }
    } while (swapped);
    printf("排序完成");
}


void sort_By_Math(LTNode* phead)
{
    if (phead == NULL || phead->next == phead)
    {
        return; // 空链表或只有一个节点,无需排序  
    }
    int swapped;
    LTNode* tail = phead->prev;
    do
    {
        LTNode* current = phead->next;
        swapped = 0;
        while (current != tail)
        {
            LTNode* next = current;
            next = current->next;
            if (current->stu.Score[1] > next->stu.Score[1])
            {
                swap(current);
                swapped = 1;
            }
            current = next;
        }
    } while (swapped);
    printf("排序完成");
}

void sort_By_Chinese(LTNode* phead)
{
    if (phead == NULL || phead->next == phead)
    {
        return; // 空链表或只有一个节点,无需排序  
    }
    int swapped;
    LTNode* tail = phead->prev;
    do
    {
        LTNode* current = phead->next;
        swapped = 0;
        while (current != tail)
        {
            LTNode* next = current;
            next = current->next;
            if (current->stu.Score[0] > next->stu.Score[0])
            {
                swap(current);
                swapped = 1;
            }
            current = next;
        }

    } while (swapped);
    printf("排序完成");
}


void sort_By_ave(LTNode*phead)
{
    if (phead == NULL || phead->next == phead) 
    {
                return; // 空链表或只有一个节点,无需排序  
    }
   

    int swapped;
    LTNode* tail = phead->prev;
    
    do
    { 
        LTNode* current = phead->next;
        swapped = 0;
        while (current != tail)
        {
            LTNode *next = current;
            next = current->next;
            if (current->stu.Ave > next->stu.Ave)
            {
                swap(current);
                swapped = 1;
            }
            current = next;
        }
    } while (swapped);
    printf("排序完成");
}


void Sort(LTNode* phead)
{
    printf("你想通过哪些方式来进行排序\n 1.通过平均成绩\n 2.通过语文成绩\n 3.通过数学成绩 \n 4.通过英语成绩\n");
    int choice;
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:sort_By_ave(phead);
        break;
    case 2:sort_By_Chinese(phead);
        break;
    case 3:sort_By_Math(phead);
        break;
    case 4:sort_By_English(phead);
        break;

    default:    printf("输入错误!\n");
        break;
    }

}

保存当前数据到文件
void save_to_File(LTNode* head, const char* filename) 
{
    FILE* file = fopen(filename, "w");
    if (!file) {
        perror("Failed to open file");
        return;
    }

    LTNode* current = head->next; // 假设head是循环链表的哨兵节点  
    while (current != head) {
        if (fprintf(file, " %d %9s %d %d %d %lf\n",
            current->stu.Numb, current->stu.Name,
            current->stu.Score[0], current->stu.Score[1],
            current->stu.Score[2], current->stu.Ave) < 0) 
        {
            perror("Failed to write to file");
            fclose(file);
            return;
        }
        current = current->next;
    }

    fclose(file);
    printf("数据已保存到文件成功\n");
}

//从文件中读取
LTNode* read_to_File(const char* filename,LTNode * phead)
{
    
    LTNode* tail = phead; // tail初始化为哨兵节点  
    LTNode* head = phead;


    FILE* file = fopen(filename, "r");

    if (!file)
    {
        perror("Failed to open file for reading");
        return NULL;
    }

    STU stu;
    while (fscanf(file, " %d %9s %d %d %d %lf", &stu.Numb, stu.Name, &stu.Score[0], &stu.Score[1], &stu.Score[2], &stu.Ave) == 6)
    {
        LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));
        if (!newNode)
        {
            perror("Failed to allocate memory for new node");
            // 释放已分配的内存  
            LTNode* current = head->next;
            while (current != head)
            {
                LTNode* temp = current;
                current = current->next;
                free(temp);
            }
            fclose(file);
            return NULL;
        }
        newNode->stu = stu;
        newNode->next = head; // 新节点的next指向哨兵节点  
        newNode->prev = tail; // 新节点的prev指向tail  
        tail->next = newNode; // tail的next指向新节点  
        tail = newNode; // 更新tail为新节点  
    }
    fclose(file);

     //设置最后一个节点的next指针指向哨兵节点  
    tail->next = head;
    head->prev = tail;

    return head;
}



#define PASSWORD_FILE "password_stu.txt"

// 将整数密码转换为字符串
char* int_to_string(int number) 
{
    int temp_number = number;
    int count = 0;
    //先判断密码有几位
    while (temp_number != 0) 
    {
        temp_number /= 10;
        count++;
    }
    //申请空间,最有一个用来装\0
    char* str = (char*)malloc(sizeof(char)*(count + 1));
    if (str == NULL)
    {
        printf("Memory application failed\n");
        return;
    }
    str[count] = '\0';
    while (number != 0) 
    {
        str[--count] = '0' + (number % 10);
        number /= 10;
    }
    return str;
}

// 将字符串转换为整数
int string_to_int(const char* str) 
{
    int result = 0;
    int sign = 1;
    if (*str == '-') 
    {
        sign = -1;
        str++;
    }
    while (*str != '\0') 
    {
        result = result * 10 + (*str - '0');
        str++;
    }
    return result * sign;
}

// 将整数密码写入文本文件
int write_password_to_txt_file(int password) 
{
    char* password_str = int_to_string(password);
    FILE* fp = fopen(PASSWORD_FILE, "w");
    if (fp == NULL) 
    {
        free(password_str);
        perror("Failed to open password file");
        return -1;
    }

    if (fprintf(fp, "%s", password_str) < 0) 
    {
        free(password_str);
        perror("Failed to write password to file");
        fclose(fp);
        return -1;
    }

    free(password_str);
    fclose(fp);
    return 0;
}

// 从文本文件读取整数密码
int read_password_from_txt_file() 
{
    FILE* fp = fopen(PASSWORD_FILE, "r");
    if (fp == NULL) {
        perror("Failed to open password file");
        return -1; // 或者在此处设置默认密码或抛出错误
    }

    char password_str[128]; // 假设密码不超过127位数
    fgets(password_str, sizeof(password_str), fp);
    password_str[strcspn(password_str, "\n")] = '\0'; // 去掉可能存在的换行符

    int password = string_to_int(password_str);

    fclose(fp);
    return password;
}

// 修改文本文件中的整数密码
int modify_password_in_txt_file(int old_password, int new_password) 
{
    if (read_password_from_txt_file() != old_password) 
    {
        printf("Old password does not match.\n");
        return -1;
    }

    if (write_password_to_txt_file(new_password) != 0) 
    {
        printf("Failed to modify the password.\n");
        return -1;
    }

    printf("Password successfully modified.\n");
    return 0;
}


 void change_secret(int* password)
{
     int password_1 = *password;
     printf("您当前的密码是:  ");
     // 读取并显示密码
     printf("Read password: %d\n", read_password_from_txt_file());
     printf("\n");

     

     // 修改密码
     printf("修改后的密码:  ");
     int newpassword = 0;
     scanf("%d", &newpassword);
      int end = modify_password_in_txt_file(*password, newpassword);
     
      if (end == -1)
      {
          printf("Failed to change password");
          return;
      }
      *password = newpassword;

     // 再次读取并显示密码
     printf("修改后的密码为:    ");
     printf("New read password: %d\n", read_password_from_txt_file());
     printf("\n");
     
     printf("修改密码完成,您即将退出系统!\n");
}



// 备份保存到文件中的数据到另一个文件中
 void backup_to_another_file(LTNode* phead, const char* source_filename, const char* target_filename)
 {
     // 首先从源文件读取数据到链表
     LTNode* backup_head = read_to_File(source_filename, phead);
     if (!backup_head)
     {
         printf("Failed to read from source file\n");
         return;
     }

     // 然后将链表中的数据保存到目标文件
     save_to_File(backup_head, target_filename);

 }

//学生权限下的菜单
void Stu_menu()
{
    printf("   \t\t\t      ***1.显示全部信息                         \n");
    printf("   \t\t\t      ***2.查询学生信息                         \n");
    printf("   \t\t\t      ***3.从文件加载学生信息					\n");
    printf("   \t\t\t      ***4.修改学生密码                         \n");

}

//这是学生权限
void Stu_Pri(LTNode *phead)
{
    //初始密码需要手动写到文件中
   int password= read_password_from_txt_file();
    int password__ = password;
    // 写入初始密码
    write_password_to_txt_file(password__);

    system("cls");
    printf("\t\t\t------欢迎进入到学生信息管理系统------\n");
    printf("\t\t\t------您当前拥有的权限为学生权限------\n");
    printf("\t\t\t在进入前,需要确定您的身份,请输入访问密码\n");
    int password_in = 0;
    int i = 0;
    for (i = 2; i >=0; i--)
    {
        scanf("%d", &password_in);
        if (password != password_in)
        {
            printf("\t\t\t密码错误,请重新输入,你还剩%d次机会\n", i);
        }
        else
        {
            break;
        }
        if (i == 0) return;
    }
    
    system("cls");
    int EO = 0;//EO是控制执行的次数,
    system("cls");
    do {
        system("cls");
        Stu_menu();

        if (phead->next == NULL)
        {
            printf("\n");
            printf("\t\033[31m您的系统中还没有任何数据, 请按 3 从文件中加载数据!\n\033[0m");
        }

        int choice = 0; 
        printf("\t\t\t请输入你所需功能对应的编号\n");
        scanf("%d", &choice);
        switch (choice)
        {
        case 1:showStudent(phead);    printf("如果未找到数据,可尝试使用 3 后再次尝试\n");    break;
        case 2:search(phead);         printf("如果未找到数据,可尝试使用 3 后再次尝试\n");      break;
        case 3:phead =  read_to_File("student.txt",phead);  break;
        case 4: change_secret(&password); break;
        default: printf("\t\t\t输入错误\n"); EO = 1; break;
        }
        printf("\t\t\t请问你是否还要继续\n");
        printf("\t\t\t继续请按1,退出请按0\n");
        printf("\033[0m\033[1;31m  请在退出系统前将系统中的数据保存到文件中去 \033[0m             \n");

        scanf("%d", &EO);
    } while (EO);
}


#define PASSWORD_FILE_T "password_teacher.txt"

// 将整数密码写入文本文件
int write_password_to_txt_file_teacher(int password) 
{
    char* password_str = int_to_string(password);
    FILE* fp = fopen(PASSWORD_FILE_T, "w");
    if (fp == NULL) {
        free(password_str);
        perror("Failed to open password file");
        return -1;
    }

    if (fprintf(fp, "%s", password_str) < 0) {
        free(password_str);
        perror("Failed to write password to file");
        fclose(fp);
        return -1;
    }

    free(password_str);
    fclose(fp);
    return 0;
}

// 从文本文件读取整数密码
int read_password_from_txt_file_teacher() 
{
    FILE* fp = fopen(PASSWORD_FILE_T, "r");
    if (fp == NULL) {
        perror("Failed to open password file");
        return -1; // 或者在此处设置默认密码或抛出错误
    }

    char password_str[128]; // 假设密码不超过127位数
    fgets(password_str, sizeof(password_str), fp);
    password_str[strcspn(password_str, "\n")] = '\0'; // 去掉可能存在的换行符

    int password = string_to_int(password_str);

    fclose(fp);
    return password;
}

// 修改文本文件中的整数密码
int modify_password_in_txt_file_teacher(int old_password, int new_password) 
{
    if (read_password_from_txt_file_teacher() != old_password) 
    {
        printf("Old password does not match.\n");
        return -1;
    }

    if (write_password_to_txt_file_teacher(new_password) != 0) 
    {
        printf("Failed to modify the password.\n");
        return -1;
    }

    printf("Password successfully modified.\n");
    return 0;
}



void change_secret_teacher(int* password)
{
    int password_1 = *password;
    printf("您当前的密码是:  ");
    // 读取并显示密码
    printf("Read password: %d\n", read_password_from_txt_file_teacher());
    printf("\n");
    // 修改密码
    printf("修改后的密码:  ");
    int newpassword = 0;
    scanf("%d", &newpassword);
    int end = modify_password_in_txt_file_teacher(*password, newpassword);

    if (end == -1)
    {
        printf("Failed to change password");
        return;
    }
    *password = newpassword;

    // 再次读取并显示密码
    printf("修改后的密码为:    ");
    printf("New read password: %d\n", read_password_from_txt_file_teacher());
    printf("\n");

    printf("修改密码完成,您即将退出系统!\n");
}

//这是教师权限
void T_Pri(LTNode* phead)
{
    system("cls");
    int password = read_password_from_txt_file_teacher();

    printf("欢迎进入学生管理系统\n");
    printf("您当前所在的权限为--教师\n");
    

    int password_in = 0;
    printf("请输入你的访问密码\n");
  
    int i = 0;
    for (i = 2; i >= 0; i--)
    {
        scanf("%d", &password_in);
        if (password != password_in)
        {
            printf("\t\t\t密码错误,请重新输入,你还剩%d次机会\n", i);
        }
        else
        {
            break;
        }
        if (i == 0) return;
    }
    system("cls");

    int num = 0, choice, EO = 0;   //EO为0,默认执行一次后退出
  
   //
   do
   {
       
       menu();
       if (phead->next == NULL)
       {
           printf("\n");
           printf("\033[31m您的系统中还没有任何数据, 请按9从文件中加载数据!\n\033[0m");
           printf("\033[31m如果您已经使用9,还需添加人数,请按3插入学生信息,否则系统会重置!!\n\033[0m");

       }
       scanf("%d", &choice);
       switch (choice)
       { 
           //添加学生信息
       case 1: AddStudent(&phead);             break;
           //展示学生信息
       case 2:   showStudent(phead);           break;
           //搜索学生
       case 3:    search(phead);                    break;
           //插入学生的信息
       case 4:     insert(&phead);                 break;
           //删除某个学生的信息
       case 5:  Delete(phead);                    break;
           //更新某个学生的信息
       case 6:Updata(phead);                           break;
           //对学生的信息进行排序
       case 7: Sort(phead); break;

           //将学习的信息缓冲到文件中
       case 8:save_to_File(phead, "student.txt"); break;

       case 9:phead = read_to_File("student.txt",phead);  break;

       case 10:backup_to_another_file(phead,"student.txt", "student_copy.txt"); break;

       case 11:  change_secret_teacher(&password);                 break;

       case 12:Find_UN_pass(phead); break;
       case 0:break;
       default: printf("输入的数字有误,请检查后重新输入!\n");  break;
       }
       printf("\033[0m\033[1;31m  请在退出系统前将系统中的数据保存到文件中去 \033[0m             \n");
       printf("是否还要继续操作,继续请按 1 ,退出则按 0!\n");
       scanf("%d", &EO);
       system("cls");
   } while (EO);

}




//对不同的人进行权限设置
int main()
{ 
    LTNode* phead = Init();
    printf("\n\n\n\n\n");
    printf("\33[5m\t\t\t------欢迎进入学生信息管理系统------\033[0m\n");
    printf("\t\t\t\t访问学生权限-- 1\n");
    printf("\t\t\t\t访问管理员权限-- 2\n");
    
    int choice = 0;
    scanf("%d", &choice);
    switch (choice)
    {
        //学生权限
    case 1:Stu_Pri(phead); break;

        //管理员权限
    case 2:T_Pri(phead); break;
    default:printf("输入错误!您即将退出系统\n");
    }

   

    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值