#include<stdio.h>
#include<string.h>
#include<stdlib.h>typedef struct student
{
    int st_id;
    char st_name[20];
    double st_score;
    struct student* st_next;
}stu_t,*pstu_t;typedef struct user
{
    int us_id;
    char us_password[20];
    int us_permission;                              //注意只能输入0或者1
    struct user* us_next;
}use_t,*puse_t;void backtofun1();                                              //返回管理员查询学生信息的主界面
/*-------------------------------------将文件中信息保存到链表--------------------------------------------------*/
void file_to_user_link(puse_t* head)                            //从文件中读取数据存到链表中,建立链表。
{
    FILE *fp_src;
    char line[128];
    puse_t pnew;                                    //即将插入的节点
    puse_t ptail;                                   //当前链表的最后一个节点    char *path = "E:\\user.txt";
    fp_src = fopen(path,"r");
    if(fp_src == NULL)
    {
        fprintf(stderr,"fopen fail");
        return 1;
    }
    while(memset(line,0,sizeof(line)),fgets(line,sizeof(line),fp_src)!=NULL)
    {
        pnew = (puse_t)calloc(1,sizeof(use_t));//为新节点分配一个结构体,初始为空
        sscanf(line,"%d%s%d",&pnew->us_id,pnew->us_password,&pnew->us_permission);        if(*head == NULL)
            *head = pnew;
        else
            ptail->us_next = pnew;
        ptail = pnew;
    }
    fclose(fp_src);
}void file_to_link_student(pstu_t* head)                         //从文件中读取数据存到链表中,建立链表。
{
    FILE *fp_config;
    FILE *fp_src;
    char line[128];
    pstu_t pnew;//即将插入的节点
    pstu_t ptail;//当前链表的最后一个节点    char *path = "E:\\stu.txt";
    fp_src = fopen(path,"r");
    if(fp_src == NULL)
    {
        fprintf(stderr,"fopen fail");
        return 1;
    }
    while(memset(line,0,sizeof(line)),fgets(line,sizeof(line),fp_src)!=NULL)
    {
        pnew = (pstu_t)calloc(1,sizeof(stu_t));//为新节点分配一个结构体,初始为空
        sscanf(line,"%d%s%lf",&pnew->st_id,pnew->st_name,&pnew->st_score);        if(*head == NULL)
            *head = pnew;
        else
            ptail->st_next = pnew;
        ptail = pnew;
    }
    fclose(fp_src);
}/*----------------------------------------------登陆系统---------------------------------------------------*/
void login()                                                    //普通用户登陆后显示自己的成绩,管理员登陆后进入管理员界面
{
    pstu_t stu = NULL;
    puse_t head = NULL;
	puse_t pcur,ppre;
    char password[20];
    int ID;
    int wrongtime = 0;    //读取用户文件中的信息到用户链表中
    file_to_user_link(&head);
    file_to_link_student(&stu);    pcur = head;
    ppre = NULL;
    //没有找到符合条件的指针时候将指针依次向后挪
    //如果找到用户名且密码匹配
    while(wrongtime != 3)
    {
    printf("\n欢迎使用wyt的学生管理系统\n请输入用户名:\n");
	scanf("%d",&ID);	printf("请输入密码:");
	fflush(stdout);
	fflush(stdin);
	scanf("%s",password);
        while(pcur != NULL)
    {
      if(pcur->us_id == ID )//如果用户名找到
      {
        if(strcmp(pcur->us_password,password)== 0)//判断密码输入是不是正确
        {
            if(pcur->us_permission == 2)//如果密码输入正确,根据用户ID判断权限进入不同界面
            {
              manager();
              break;
            }
            else
            {
             common_user(stu,ID);
             break;
             }
        }
       else
       {
           printf("密码输入错误。您还有%d次输入机会",2-wrongtime);
              wrongtime++;
           if(wrongtime == 3 )
            printf("对不起,您已经连续三次输入错误密码。");
          break;       }
        }
        else                    //没有找到输入的用户名匹配的用户ID,继续向下寻找。
        {
         ppre = pcur;
        pcur = pcur->us_next;
        }
    }
    if(pcur == NULL)
       printf("没有找到用户.");    }
}
/*---------------------------------------------普通用户登陆成功后的界面------------------------------------------------------------*/
void common_user(pstu_t head,int search_id)                      //普通用户登陆成功后的界面,可以查询自己的成绩。
{
    pstu_t pcur,ppre;
    system("cls");
    pcur = head;
    ppre = NULL;    printf("hello,欢迎使用本系统查询您的成绩\n");
    //没有找到符合条件的指针时候将指针依次向后挪
    while(pcur != NULL && pcur->st_id != search_id)
    {
        ppre = pcur;
        pcur = pcur->st_next;
    }
    if(pcur != NULL)
        fprintf(stdout,"%5d%10s%7.2f",pcur->st_id,pcur->st_name,pcur->st_score);
	else
        printf("没有找到该学生。");}
/*---------------------------------------------管理员登陆成功后界面--------------------------------------------------------*/
void manager()                                                   //管理员登陆成功后的界面。
{
    int i;    pstu_t stu = NULL;
    puse_t user = NULL;
    system("cls");
    //读取用户文件中的信息到用户链表中
    file_to_user_link(&user);    //读取学生文件中的信息到学生链表中
    file_to_link_student(&stu);    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("请输入您的选择:\n");
    scanf("%d",&i);
    switch(i)
    {
        case 1:fun1();
        break;
        case 2:fun2();                      //增加学生信息。
        break;
        case 3:fun3();
        break;
        case 4:fun4();
        break;
        case 5:fun5();
        break;
        case 6:fun6();
        break;
        case 7:fun7();
        break;
        case 8:fun8();
        break;
        case 9:exit(0);
            break;
    }}
void backtofun()
{
    for(;;)
    {
        printf("\n还需要操作么?如果需要操作请输入:yes,否则请输入:no\n");
         char flag[20];
          scanf("%s",flag);
        if(strcmp(flag,"yes")==0)
             manager();
        else if(strcmp(flag,"no")==0)
            exit(0);
    printf("输入错误,请重新输入\n");
    }
}
/*--------------------------------------------管理员查询学生信息界面--------------------------------------------------------------*/void search_student(pstu_t head)                                 //查询所有学生的信息
{
    pstu_t pcur;
    pcur = head;
    while(pcur != NULL)
    {
        printf("%-5d%-10s%5.2f\n",pcur->st_id,pcur->st_name,pcur->st_score);
        pcur = pcur->st_next;
    }
    backtofun1();
}
void search_by_id(pstu_t head)                                   //按学号搜索。
{
    pstu_t pcur,ppre;
    pcur = head;
    ppre = NULL;    int search_id;
	printf("\n按学号查找\n请输入学号");
	scanf("%d",&search_id);    //没有找到符合条件的指针时候将指针依次向后挪
    while(pcur != NULL && pcur->st_id != search_id)
    {
        ppre = pcur;
        pcur = pcur->st_next;
    }
    if(pcur != NULL)
        fprintf(stdout,"%5d%10s%7.2f",pcur->st_id,pcur->st_name,pcur->st_score);
	else
        printf("没有找到该学生。");	backtofun1();
}
void search_by_name(pstu_t head)                                  //按姓名搜索。
{
    pstu_t pcur,ppre;
    pcur = head;
    ppre = NULL;	char search_name[100];
	printf("\n按姓名查找\n请输入姓名");
	fflush(stdout);
	fflush(stdin);
	fgets(search_name,sizeof(search_name),stdin);    //没有找到符合条件的指针时候将指针依次向后挪
    while(pcur != NULL && memcmp(pcur->st_name,search_name,strlen(pcur->st_name)) != 0)
    {
        ppre = pcur;
        pcur = pcur->st_next;
    }
    if(pcur != NULL)
        fprintf(stdout,"%5d%10s%7.2f",pcur->st_id,pcur->st_name,pcur->st_score);
	else
        printf("没有找到该学生。");    backtofun1();
}
void fun1()                                                       //管理员查询学生信息界面。
{
    pstu_t stu = NULL;
    int i;    system("cls");
    file_to_link_student(&stu);
    printf("学生管理系统查询信息界面\n");
    printf("1.查询所有学生信息\n");
    printf("2.按学号查询学生信息\n");
    printf("3.按姓名查询学生信息\n");
    printf("4.返回上一级");
    printf("请输入您的选择:\n");
    scanf("%d",&i);    switch(i)
    {
        case 1:search_student(stu);
        break;
        case 2:search_by_id(stu);
        break;
        case 3:search_by_name(stu);
        break;
        case 4:manager();
            break;
    }
}void backtofun1()                                                 //返回管理员查询学生信息的主界面
{
    for(;;)
    {
        printf("\n还需要操作么?如果需要操作请输入:yes,否则请输入:no\n");
        char flag[20];
          scanf("%s",flag);
    if(strcmp(flag,"yes")==0)
       fun1();
    else if(strcmp(flag,"no")==0)
      exit(0);
         printf("输入错误,请重新输入\n");
    }
}/*--------------------------------------------学生增加---------------------------------------------------------------------------------*/
void link_to_file_student(pstu_t head)                            //将学生链表中的数据保存到学生文件中。
{
    FILE *fp;
    pstu_t pcur;
	char *path = "E:\\stu.txt";
    pcur = head;    if((fp=fopen(path,"w"))==NULL)                  //如果用a的话会重复写入,因为是用指针写入的,
        {
          printf("cannot open file");
          exit(0);
        }
    while(pcur != NULL)
    {
        fprintf(fp,"%5d%10s%7.2f\n",pcur->st_id,pcur->st_name,pcur->st_score);
        pcur = pcur->st_next;
    }
    fclose(fp);
}void search_all_student(pstu_t head)                              //打印所有学生的信息
{
    pstu_t pcur;
    pcur = head;
    while(pcur != NULL)
    {
        printf("%-5d%-10s%5.2f\n",pcur->st_id,pcur->st_name,pcur->st_score);
        pcur = pcur->st_next;
    }
}void add_stu(pstu_t *head)                                       //增加学生信息
{    int i;
    pstu_t pcur,ppre;
    pstu_t pnew;
    char line[128];	system("cls");
    printf("学生管理系统录入学生信息界面\n");
    printf("请输入要录入的学生的信息:\n");
    printf("学号 姓名 成绩 \n");
    fflush(stdout);                                 //要加这几句,否则缓冲区中会有东西导致程序出错    fflush(stdin);
    memset(line,0,sizeof(line));
    fgets(line,sizeof(line),stdin);        pnew=(pstu_t)calloc(1,sizeof(stu_t));
        sscanf(line,"%d%s%lf",&pnew->st_id,pnew->st_name,&pnew->st_score);        pcur = *head;
        ppre = NULL;        while(pcur !=NULL && pcur->st_id<=pnew->st_id)
		{
				ppre = pcur;
				pcur = pcur->st_next;
		}
		if(ppre == NULL)
		{
			pnew->st_next = *head;
			*head = pnew;
		}
		else
		{
				ppre->st_next = pnew;
				pnew->st_next = pcur;
		}
}void fun2()                                                      //增加学生信息的主函数
{
    pstu_t stu = NULL;
    file_to_link_student(&stu);
    add_stu(&stu);    link_to_file_student(stu);
    search_all_student(stu);
    backtofun();}
/*------------------------------------------修改学生信息---------------------------------------------------------------*/void student_change(pstu_t *head,int val)                        //更改学生的函数
{
    //找到要修改的节点,把原来的数据置为空,然后输入新的数据
    pstu_t ppre,pcur;
    ppre = NULL;
    pcur = *head;
    pstu_t ptem;    char line[128];
    while(pcur!=NULL && pcur->st_id != val)
    {
        ppre = pcur;
        pcur = pcur->st_next;
    }    if(pcur->st_id == val)
    {
        memset(line,0,sizeof(line));
        printf("输入要修改的值\n学号 姓名 成绩\n");
        fflush(stdout);        fflush(stdin);
        fgets(line,sizeof(line),stdin);
        ptem = (pstu_t)calloc(1,sizeof(stu_t));
        sscanf(line,"%d%s%lf",&ptem->st_id,ptem->st_name,&ptem->st_score);
        pcur->st_id = ptem->st_id;
        memcpy(pcur->st_name,ptem->st_name,sizeof(ptem->st_name));
        pcur->st_score = ptem->st_score;
    }
}void fun3()                                                     //修改学生信息的主函数
{
    int n;
    pstu_t stu = NULL;
    file_to_link_student(&stu);
    search_all_student(stu);    printf("输入要修改的学号:\n");
    scanf("%d",&n);
    student_change(&stu,n);
    search_all_student(stu);
    link_to_file_student(stu);    backtofun();
}/*------------------------------------------删除学生---------------------------------------------------------------*/
void student_delete(pstu_t *head,int val)                       //删除学生
{
    pstu_t pcur,ppre;
    pcur = *head;
    ppre = NULL;
    //没有找到符合条件的指针时候将指针依次向后挪
    while(pcur != NULL && pcur->st_id != val)
    {
        ppre = pcur;
        pcur = pcur->st_next;
    }    //上述退出循环时候的指针要么是要找的指针,要么是尾部指针没有找到要删除的节点
    if(pcur != NULL)
    {
        if(ppre == NULL)//如果要删除的节点就是头指针
        {
            *head = pcur->st_next;
            free(pcur);
            pcur = NULL;
        }
        else  //要删除的节点不是头指针
        {
            ppre->st_next = pcur->st_next;
            free(pcur);
            pcur = NULL;
        }    }
}
void fun4()                                                    //删除学生的主函数
{
    int n;
    pstu_t stu = NULL;
    file_to_link_student(&stu);
    search_all_student(stu);    printf("输入要删除的学号:\n");
    scanf("%d",&n);
    student_delete(&stu,n);
    search_all_student(stu);
    link_to_file_student(stu);    backtofun();
}/*------------------------------------------查询用户信息------------------------------------------------------------*/
void search_user(puse_t head)                                 //查询所有用户的信息
{
    puse_t pcur;
    system("cls");
    pcur = head;
    printf("欢迎进入用户信息查询界面 \n");
    printf("用户ID  密码  权限(2代表管理员,1代表普通用户)\n");
    while(pcur != NULL)
    {
        printf("%-5d%-10s%-5d\n",pcur->us_id,pcur->us_password,pcur->us_permission);
        pcur = pcur->us_next;
    }
}void fun5()                                                  //查询用户信息主函数
{
    printf("查询用户信息");
    puse_t head = NULL;
	 file_to_user_link(&head);
     search_user(head);    backtofun();
}/*------------------------------------------增加用户信息-----------------------------------------------------------------*/
void link_to_file_user(puse_t head)                         //将链表中的数据保存到用户文件中。
{
    FILE *fp;
    puse_t pcur;
	char *path = "E:\\user.txt";
    pcur = head;    if((fp=fopen(path,"w"))==NULL)//如果用a的话会重复写入,因为是用指针写入的,
        {
          printf("cannot open file");
          exit(0);
        }
    while(pcur != NULL)
    {
        fprintf(fp,"%-5d%-10s%-5d\n",pcur->us_id,pcur->us_password,pcur->us_permission);
        pcur = pcur->us_next;
    }
    fclose(fp);
}void add_user(puse_t *head)                                 //增加用户信息
{    int i;
    puse_t pcur,ppre;
    puse_t pnew;
    char line[128];	system("cls");
    printf("学生管理系统录入用户信息界面\n");
    printf("请输入要录入的用户的信息:\n");
    printf("用户ID  密码 权限(2代表管理员,1代表普通用户) \n");
    fflush(stdout);
    fflush(stdin);
    memset(line,0,sizeof(line));
    fgets(line,sizeof(line),stdin);        pnew = (puse_t)calloc(1,sizeof(use_t));//为新节点分配一个结构体,初始为空
        sscanf(line,"%d%s%d",&pnew->us_id,pnew->us_password,&pnew->us_permission);        pcur = *head;
        ppre = NULL;        while(pcur !=NULL && pcur->us_id<=pnew->us_id)
		{
				ppre = pcur;
				pcur = pcur->us_next;
		}
		if(ppre == NULL)
		{
			pnew->us_next = *head;
			*head = pnew;
		}
		else
		{
				ppre->us_next = pnew;
				pnew->us_next = pcur;
		}}
void fun6()                                                 //增加用户信息主函数
{
    printf("增加用户信息");
    puse_t head = NULL;
    file_to_user_link(&head);
     search_user(head);
     add_user(&head);
     link_to_file_user(head);
     search_user(head);
    backtofun();
}/*------------------------------------------修改用户信息-----------------------------------------------------------------*/
void user_change(puse_t *head,int val)                      //修改用户信息
{
    //找到要修改的节点,把原来的数据置为空,然后输入新的数据
    puse_t ppre,pcur;
    ppre = NULL;
    pcur = *head;
    puse_t ptem;    char line[128];
    while(pcur!=NULL && pcur->us_id != val)
    {
        ppre = pcur;
        pcur = pcur->us_next;
    }    if(pcur->us_id == val)
    {
        memset(line,0,sizeof(line));
        printf("输入要修改的值\n用户ID  密码 权限(2代表管理员,1代表普通用户) \n");
        fflush(stdout);        fflush(stdin);
        fgets(line,sizeof(line),stdin);
        ptem = (puse_t)calloc(1,sizeof(use_t));//为新节点分配一个结构体,初始为空
        sscanf(line,"%d%s%d",&ptem->us_id,ptem->us_password,&ptem->us_permission);        pcur->us_id = ptem->us_id;
        memcpy(pcur->us_password,ptem->us_password,sizeof(ptem->us_password));
        pcur->us_permission = ptem->us_permission;
    }
}void fun7()                                                 //修改用户信息主函数
{
    printf("更新用户信息");
    int n;
    puse_t head = NULL;
	 file_to_user_link(&head);
     search_user(head);     printf("输入要修改的用户ID:\n");
    scanf("%d",&n);
    user_change(&head,n);
    search_user(head);
    link_to_file_user(head);
    backtofun();
}/*------------------------------------------删除用户信息-----------------------------------------------------------------*/
void user_delete(puse_t *head,int val)                       //s删除用户信息
{
    puse_t pcur,ppre;
    pcur = *head;
    ppre = NULL;
    //没有找到符合条件的指针时候将指针依次向后挪
    while(pcur != NULL && pcur->us_id != val)
    {
        ppre = pcur;
        pcur = pcur->us_next;
    }    //上述退出循环时候的指针要么是要找的指针,要么是尾部指针没有找到要删除的节点
    if(pcur != NULL)
    {
        if(ppre == NULL)//如果要删除的节点就是头指针
        {
            *head = pcur->us_next;
            free(pcur);
            pcur = NULL;
        }
        else  //要删除的节点不是头指针
        {
            ppre->us_next = pcur->us_next;
            free(pcur);
            pcur = NULL;
        }    }
}
void fun8()                                                 //修改用户信息主函数
{
    printf("删除用户信息");
    int n;
    puse_t head = NULL;
	 file_to_user_link(&head);
     search_user(head);     printf("输入要删除的用户ID:\n");
    scanf("%d",&n);
    user_delete(&head,n);
    search_user(head);
    link_to_file_user(head);
    backtofun();
}/*-------------------------------------------主函数————————————————————————————————————————————————*/
void main()
{
    login();
}