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