双向链表的学生管理系统。
可以实现
1. 添加指定人数的学生信息
2. 删除指定学号信息
3. 查看当前链表内容
4. 当前的班级人数
5. 手动保存信息到文件
6. 修改指定学号学生信息
7. 根据姓名或学号查找学生
0. 退出系统并保存文件
在主函数最开始,打开指定xls文件,如果文件不存在就会直接创建空白文件(文件类型可以改,更改后,把保存文件的函数输出格式稍加更改会更美观)
然后打印目录,选择自己想要实现的操作
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
//此处写入你要读取的文件名与文件类型,如果文件不存在会直接创建新的空文件
#define NAME_FI "D:\\桌面\\学生信息.xls"
int ALL=0;//全局变量表示 当前总人数
//定义结构体双链表
typedef struct STU
{
//数据域
long id;
char name[20];
char sex;
float score;
//指针域
struct STU *prev;//指向前一个节点
struct STU *pnext;//指向后一个节点
}STUDENT;
//链表头
STUDENT *phead = NULL;
STUDENT *ptemp = NULL;
//创建一个结构体
STUDENT *Create_Node(void)
{
STUDENT *ptr = (STUDENT *)calloc(1,sizeof(STUDENT));
ptr->prev = NULL;
ptr->pnext = NULL;
return ptr;
}
//函数声明
void menu();
void add_Node(void);
void dele(void);
void revise(void);
void SListPrint(void);
void save_file(void);
void read_file(void);
void search(void);
//主函数
int main()
{
phead = Create_Node();
read_file();//读取文件中的内容到链表
while(1)
{
int n=0;
menu();//目录
scanf("%d",&n);
switch(n)
{
case 1: add_Node();break;//添加指定数量的学生信息
case 2: dele();break;//删除指定学号的学生信息
case 3: SListPrint();break;//打印链表
case 4: printf("当前班级共%d人\n",ALL);break;//打印当前班级总人数
case 5: save_file();break;//保存当前信息到文件中
case 6: revise();break;//根据学号更改学生信息
case 7: search();break;//按姓名或学号查找学生信息
case 0: save_file();return 0;break;//保存当前信息到文件中并关闭程序
}
//也可以把save_file放在这里,表示每执行一个操作后会自动保存
}
}
/*****************************
定义一个函数,输出菜单
******************************/
void menu()
{
printf("*******学生信息管理系统********\n\t");
printf("1. 添加信息\n\t");
printf("2. 删除信息\n\t");
printf("3. 查看当前内容\n\t");
printf("4. 当前的班级人数\n\t");
printf("5. 手动保存信息到文件\n\t");
printf("6. 修改学生信息\n\t");
printf("7. 根据姓名或学号查找学生\n\t");
printf("0. 退出系统并保存文件\n");
printf("********************************\n");
printf("请输入你要想执行的操作(0-7):\n");
}
//添加学生信息,并按照学号排序
void add_Node(void)
{
int n=0,i=ALL,j,flag=0;
printf("请输入你要添加的人数\n");
scanf("%d",&n);
if(n>0)
{
do{
int flag=1;//标志位,判断是否已经输入
//创建一个新节点
STUDENT *pnew = Create_Node();
ptemp = phead;
while(flag !=0)
{
flag=0;
printf("输入第%d个学生ID:\n",i+1);
scanf("%d",&pnew->id);
while(ptemp->pnext!=NULL)
{
if(ptemp->pnext->id==pnew->id)
{flag=1;printf("该学号已存在,请重新输入\n");break;}
if(pnew->id<ptemp->pnext->id)
break;
ptemp=ptemp->pnext;
}
}
//输入学生名字
printf("输入第%d个学生名字:\n",i+1);
scanf("%s",pnew->name);
getchar();
printf("输入第%d个学生性别:\n",i+1);
scanf("%c",&pnew->sex);
printf("输入第%d个学生成绩:\n",i+1);
scanf("%f",&pnew->score);
if(ptemp->pnext==NULL)
{
ptemp->pnext=pnew;
pnew->prev=ptemp;
}
else
{
pnew->pnext = ptemp->pnext;
pnew->prev=ptemp;
ptemp->pnext=pnew;
pnew->pnext->prev=pnew;
}
i++;
}while(i<ALL+n);
printf("添加完成\n");
ALL+=n;
}
}
//删除学生信息
void dele(void)
{
int id=0,flag=0;
STUDENT *pdele;
printf("请输入你要删除学生的学号\n");
scanf("%d",&id);
ptemp=phead;
if(phead->pnext==NULL)
printf("当前表格为空\n");
else
{
if(id==ptemp->id)//删除第一个元素
{
pdele = ptemp;
phead = ptemp->pnext;
ptemp->pnext->prev=phead;
free(pdele);
ALL-=1;
}
else
{
while(ptemp->pnext!=NULL)
{
if(id == ptemp->pnext->id)//如果得到要删除的前一个元素跳出
break;
ptemp=ptemp->pnext;
}
if(ptemp->pnext == NULL)//倒数第二个元素
printf("未找到该学生\n");
else
{
pdele= ptemp->pnext;//要删除元素的地址
if(pdele->pnext==NULL)//最后一个
{
free(pdele);
ptemp->pnext=NULL;
}
else//中间
{
ptemp->pnext=pdele->pnext;
pdele->pnext->prev=ptemp;
free(pdele);
}
printf("删除成功\n");
ALL-=1;
}
}
}
}
/*函数名:revise()
函数作用:修改函数
实现查找学号然后修改其内容,当修改后的学号存在时,
提示重复,重新修改
*/
void revise(void)
{
int id;
char name[20];
printf("请输入你要修改的学生学号\n");
scanf("%d",&id);
ptemp=phead;
STUDENT *P=NULL;
P=phead;
int cnt=0;
if(phead->pnext==NULL)
printf("当前表格为空\n");
else
{
while(ptemp->pnext!=NULL)
{
if(id==ptemp->pnext->id)
break;
ptemp=ptemp->pnext;
}
if(ptemp->pnext==NULL)
{
printf("未找到该学生");
}
else
{
printf("请输入你要修改的信息\n");
printf("请输入你要修改的学生学号\n");
scanf("%d",&ptemp->pnext->id);
while(P->pnext!=NULL)
{
if(ptemp->pnext->id == P->pnext->id)
cnt++;
P=P->pnext;
}
if(cnt!=1)
{
printf("该学号已存在,请重新输入\n");
ptemp->pnext->id=id;
cnt=0;
return ;
}
printf("请输入你要修改的学生姓名\n");
scanf("%s",ptemp->pnext->name);
getchar();
printf("请输入你要修改的学生性别\n");
scanf("%c",&ptemp->pnext->sex);
printf("请输入你要修改的学生成绩\n");
scanf("%f",&ptemp->pnext->score);
}
}
}
/*函数名search()
函数功能:输入学生姓名或学号查询学生信息
*/
void search(void)
{
//声明两个子函数
void search_name(void);
void search_id(void);
while(1)
{
int n;
printf("请输入你要查询的方式\n1.姓名查询\t2.学号查询\n\t0.退出查询\n");
scanf("%d",&n);
switch(n)
{
case 1:search_name();break;
case 2:search_id();break;
case 0:return;break;
}
}
}
//search子函数:根据姓名查询学生信息
void search_name(void)
{
void print_stu(void);
ptemp=phead;
int flag=0;
char name[20];
printf("请输入学生姓名\n");
scanf("%s",name);
printf("学号\t\t姓名\t\t性别\t\t成绩\n");
//遍历链表找到姓名相同的
if(phead->pnext==NULL)
printf("当前表格为空\n");
else
{
while(ptemp->pnext!=NULL)
{
if(!strcmp(name,ptemp->pnext->name))
{
print_stu();
flag=1;
}
ptemp=ptemp->pnext;
}
if(ptemp->pnext==NULL&&flag==0)
printf("未找到该学生\n");
}
}
//search子函数:根据学号查询学生信息
void search_id(void)
{
void print_stu(void);
ptemp=phead;
int flag=0,id=0;
printf("请输入学生学号\n");
scanf("%d",&id);
printf("学号\t\t姓名\t\t性别\t\t成绩\n");
//遍历链表找到姓名相同的
if(phead->pnext==NULL)
printf("当前表格为空\n");
else
{
while(ptemp->pnext!=NULL)
{
if(id==ptemp->pnext->id)
{
print_stu();
flag=1;
}
ptemp=ptemp->pnext;
}
if(ptemp->pnext==NULL&&flag==0)
printf("未找到该学生\n");
}
}
//打印单一学生信息(用在了search中)
void print_stu(void)
{
printf("%-8d\t",ptemp->pnext->id);
printf("%-8s\t",ptemp->pnext->name);
printf("%-8c\t",ptemp->pnext->sex);
printf("%-8.1f\n",ptemp->pnext->score);
}
//读取文件内容到寄存器
void read_file(void)
{
FILE *fp=fopen(NAME_FI, "a+");
char line[256];
ptemp=phead;
STUDENT* pnew = NULL;
rewind(fp);
while(!feof(fp))
{
fseek(fp,-1,1);
pnew = Create_Node();
fgets(line,sizeof(line),fp);//缓冲区域,接收第一行目录
if(fscanf(fp,"%d %s %c %f\n",&pnew->id,pnew->name,&pnew->sex,&pnew->score)==EOF)break;
pnew->prev=ptemp;
if(ptemp!=NULL)
ptemp->pnext=pnew;
ptemp=pnew;
ALL++;
}
fclose(fp);
}
//将信息保存在文件中
void save_file(void)
{
FILE *fp=fopen(NAME_FI, "w+");
fprintf(fp,"%-8s\t%-8s\t%-8s\t%-8s\n","学号","姓名","性别","成绩");//文件首行打印提示信息
STUDENT *p =phead->pnext;
if (fp == NULL)
{
printf("打开失败\n");
exit(-1);
}
else
printf("文件打开成功\n");
for(int i=0;i<ALL;i++)
{
fprintf(fp,"%-8d\t%-8s\t%-8c\t%-.2f\n",p->id,p->name,p->sex,p->score);
p=p->pnext;
}
printf("信息保存成功\n");
fclose(fp);
}
//打印链表
void SListPrint(void)
{
printf("学号\t\t姓名\t\t性别\t\t成绩\n");
ptemp = phead;
while(ptemp->pnext!=NULL)
{
printf("%-8d\t",ptemp->pnext->id);
printf("%-8s\t",ptemp->pnext->name);
printf("%-8c\t",ptemp->pnext->sex);
printf("%-8.1f\n",ptemp->pnext->score);
ptemp = ptemp->pnext ;
}
printf("打印完成\n");
}