c语言 文件链表实现最简单的学生管理系统

#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();

}