1、设计要求
使用带头结点的链表存储学生的基本信息:
学号 姓名 成绩
要求:
① 学号不允许重复
② 显示菜单
录入学生信息
删除学生信息
根据学号删除
根据姓名删除
返回上一层
修改学生信息
可以选择修改指定属性
查找学生信息
按姓名查找
按学号查找
返回上一层
显示学生信息
按学号升序显示
按成绩降序显示
按成绩升序显示
返回上一层
退出
③ 程序运行从文件加载数据
程序结束将数据存储到文件中
2、代码设计
2.1 主函数--main.c
显示主菜单,然后通过switch--case进入对应的功能函数。
#include <stdio.h>
#include <unistd.h>
#include "stu.h"
int main(){
struct stu *head=NULL;
head=creat_stu();
read_file(head);
printf("加载中...\n");
sleep(2);
int flag=1;
int x;
while(flag)
{
printf("----------------------\n");
printf("| 1、录入学生信息 |\n");
printf("| 2、删除学生信息 |\n");
printf("| 3、修改学生信息 |\n");
printf("| 4、查找学生信息 |\n");
printf("| 5、显示学生信息 |\n");
printf("| 0、退出 |\n");
printf("----------------------\n");
printf("请选择功能:");
scanf("%d",&x);
while(getchar()!='\n');
switch(x)
{
case 1:
add_stu(head);
break;
case 2:
del_stu(head);
break;
case 3:
mod_stu(head);
break;
case 4:
search_stu(head);
break;
case 5:
display_stu(head);
break;
case 0:
flag=0;
break;
default:
printf("输入有误,请重新输入!\n");
break;
}
}
int s=write_file(head);
if(s==0)
{
printf("写入成功\n");
}
else
{
printf("写入失败\n");
}
return 0;
}
2.2 函数功能实现--stu.c
struct stu* creat_stu(); 创建一个新的学生信息的节点
① 录入学生信息
void add_stu(struct stu *head); 将学生信息录入
② 删除学生信息
void search_stu(struct stu *head); 显示一个查找学生信息的子菜单,通过switch--case选择根据学号、姓名还是成绩来查找学生信息
struct stu* id_search(struct stu *head); 根据学号查找学生信息,将查询到的学生节点返回出去
struct stu* name_search(struct stu *head); 根据姓名查找学生信息,将查询到的学生节点返回出去
struct stu* grade_search(struct stu *head); 根据成绩查找学生信息,将查询到的学生节点返回出去
void show_stu(struct stu *p); 根据学生节点,显示学生信息
③ 修改学生信息
void del_stu(struct stu *head); 显示一个删除学生信息的子菜单,通过switch--case选择根据学号或姓名来删除学生信息
void id_del(struct stu *head); 根据学号删除学生信息
void name_del(struct stu *head); 根据姓名删除学生信息
④ 查找学生信息
void mod_stu(struct stu *head); 显示一个修改学生信息的子菜单,通过switch--case选择修改学号、姓名还是成绩
void id_mod(struct stu *head); 修改学号
void name_mod(struct stu *head); 修改姓名
void grade_mod(struct stu *head); 修改成绩
⑤ 显示学生信息
void display_stu(struct stu *head); 显示一个显示学生信息的子菜单,通过switch--case选择通过何种方式将学生的信息呈现出来
void id_up(struct stu *head); 按学号升序排列
void grade_down(struct stu *head); 按成绩降序排列
void grade_up(struct stu *head); 按成绩升序排列
void show_list(struct stu *head); 将排列好的链表显示出来
⑥ 从文件读写操作
int read_file(struct stu *head); 程序运行从文件加载数据
int write_file(struct stu *head); 程序结束将数据存储到文件中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stu.h"
/*创建节点*/
struct stu* creat_stu()
{
struct stu *pnew=NULL;
pnew=(struct stu*)malloc(sizeof(struct stu));
if(pnew==NULL)
{
printf("malloc error!%s,%d\n",__FILE__,__LINE__);
exit(-1);
}
pnew->next=NULL;
return pnew;
}
/*录入操作*/
void add_stu(struct stu *head)
{
struct stu *pnew=NULL;
pnew=creat_stu();
printf("----------------\n");
printf(" 请输入学号:");
scanf("%d",&pnew->id);
while(getchar()!='\n');
printf(" 请输入姓名:");
scanf("%s",pnew->name);
while(getchar()!='\n');
printf(" 请输入成绩:");
scanf("%d",&pnew->grade);
while(getchar()!='\n');
printf("----------------\n");
struct stu *p=head->next;
while(p!=NULL)
{
if(p->id == pnew->id)
{
printf("录入失败,学号重复!\n");
free(pnew);
return ;
}
p=p->next;
}
// if(head->next=NULL)
// {
// head->next=pnew;
// }
// else
// {
pnew->next=head->next;
head->next=pnew;
// }
return ;
}
/*查找操作*/
void search_stu(struct stu *head)
{
int flag=1;
int x;
struct stu *id=NULL;
struct stu *name=NULL;
while(flag)
{
printf("----------------------\n");
printf("| 1.根据学号查找 |\n");
printf("| 2.根据姓名查找 |\n");
printf("| 0.返回上一层 |\n");
printf("----------------------\n");
printf("请选择功能:");
scanf("%d",&x);
while(getchar()!='\n');
switch(x)
{
case 1:
id=id_search(head);
show_stu(id);
break;
case 2:
name=name_search(head);
show_stu(name);
break;
case 0:
flag=0;
break;
default:
printf("输入有误,请重新输入!\n");
break;
}
}
}
struct stu* id_search(struct stu *head)
{
int id;
printf("请输入学号:");
scanf("%d",&id);
while(getchar()!='\n');
struct stu *p=head->next;
while(p!=NULL)
{
if(p->id==id)
{
return p;
}
p=p->next;
}
return NULL;
}
struct stu* name_search(struct stu *head)
{
char name[32];
printf("请输入姓名:");
scanf("%s",name);
while(getchar()!='\n');
struct stu *p=head->next;
while(p!=NULL)
{
if(strcmp(p->name,name) == 0)
{
return p;
}
p=p->next;
}
return NULL;
}
struct stu* grade_search(struct stu *head)
{
int grade;
printf("请输入成绩:");
scanf("%d",&grade);
while(getchar()!='\n');
struct stu *p=head->next;
while(p!=NULL)
{
if(p->grade==grade)
{
return p;
}
p=p->next;
}
return NULL;
}
void show_stu(struct stu *p)
{
if(p==NULL)
{
printf("输入的信息不存在!\n");
return ;
}
printf("学号:%d\n姓名:%s\n成绩:%d\n",p->id,p->name,p->grade);
return ;
}
/*删除操作*/
void del_stu(struct stu *head)
{
int flag=1;
int x;
while(flag)
{
printf("----------------------\n");
printf("| 1.根据学号删除 |\n");
printf("| 2.根据姓名删除 |\n");
printf("| 0.返回上一层 |\n");
printf("----------------------\n");
printf("请选择功能:");
scanf("%d",&x);
while(getchar()!='\n');
switch(x)
{
case 1:
id_del(head);
break;
case 2:
name_del(head);
break;
case 0:
flag=0;
break;
default:
printf("输入有误,请重新输入!\n");
break;
}
}
}
void id_del(struct stu *head)
{
struct stu *pdel=NULL;
pdel=id_search(head);
if(pdel==NULL)
{
printf("输入的信息不存在!\n");
return ;
}
struct stu *p=head;
while(p->next!=pdel)
{
p=p->next;
}
p->next=pdel->next;
free(pdel);
printf("删除成功!\n");
return ;
}
void name_del(struct stu *head)
{
struct stu *pdel=NULL;
pdel=name_search(head);
if(pdel==NULL)
{
printf("输入的信息不存在!\n");
return ;
}
struct stu *p=head;
while(p->next!=pdel)
{
p=p->next;
}
p->next=pdel->next;
free(pdel);
printf("删除成功!\n");
return ;
}
/*修改操作*/
void mod_stu(struct stu *head)
{
int flag=1;
int x;
while(flag)
{
printf("----------------------\n");
printf("| 1.根据学号修改 |\n");
printf("| 2.根据姓名修改 |\n");
printf("| 3.根据成绩修改 |\n");
printf("| 0.返回上一层 |\n");
printf("----------------------\n");
printf("请选择功能:");
scanf("%d",&x);
while(getchar()!='\n');
switch(x)
{
case 1:
id_mod(head);
break;
case 2:
name_mod(head);
break;
case 3:
grade_mod(head);
break;
case 0:
flag=0;
break;
default:
printf("输入有误,请重新输入!\n");
break;
}
}
}
void id_mod(struct stu *head)
{
struct stu *p=NULL;
p=id_search(head);
if(p==NULL)
{
printf("输入的信息不存在!\n");
return ;
}
int n;
printf("请输入修改后的学号:");
scanf("%d",&n);
while(getchar()!='\n');
p->id=n;
return ;
}
void name_mod(struct stu *head)
{
struct stu *p=NULL;
p=name_search(head);
if(p==NULL)
{
printf("输入的信息不存在!\n");
return ;
}
char n[32];
printf("请输入修改后的姓名:");
scanf("%s",n);
while(getchar()!='\n');
strcpy(p->name,n);
return ;
}
void grade_mod(struct stu *head)
{
struct stu *p=NULL;
p=grade_search(head);
if(p==NULL)
{
printf("输入的信息不存在!\n");
return ;
}
int n;
printf("请输入修改后的成绩:");
scanf("%d",&n);
while(getchar()!='\n');
p->grade=n;
return ;
}
/*显示操作*/
void display_stu(struct stu *head)
{
int flag=1;
int x;
while(flag)
{
printf("----------------------\n");
printf("| 1.根据学号升序显示 |\n");
printf("| 2.根据成绩降序显示 |\n");
printf("| 3.根据成绩升序显示 |\n");
printf("| 0.返回上一层 |\n");
printf("----------------------\n");
printf("请选择功能:");
scanf("%d",&x);
while(getchar()!='\n');
switch(x)
{
case 1:
id_up(head);
show_list(head);
break;
case 2:
grade_down(head);
show_list(head);
break;
case 3:
grade_up(head);
show_list(head);
break;
case 0:
flag=0;
break;
default:
printf("输入有误,请重新输入!\n");
break;
}
}
}
void id_up(struct stu *head)
{
struct stu *pmax=NULL;
struct stu *p=NULL;
struct stu *phead=head->next;
head->next=NULL;
struct stu *pnew=NULL;
while(phead!=NULL)
{
//找出最大值
pmax=phead;
p=phead;
while(p!=NULL)
{
if(p->id > pmax->id)
{
pmax=p;
}
p=p->next;
}
//将其移出
if(pmax==phead)
{
phead=phead->next;
}
else
{
p=phead;
while(p->next != pmax)
{
p=p->next;
}
p->next=pmax->next;
}
pmax->next=NULL;
//加入新链表
pmax->next=pnew;
pnew=pmax;
}
head->next=pnew;
return ;
}
void grade_down(struct stu *head)
{
struct stu *pmax=NULL;
struct stu *p=NULL;
struct stu *phead=head->next;
head->next=NULL;
struct stu *pnew=NULL;
struct stu *tail=NULL;
while(phead!=NULL)
{
//找出最大值
pmax=phead;
p=phead;
while(p!=NULL)
{
if(p->grade > pmax->grade)
{
pmax=p;
}
p=p->next;
}
//将其移出
if(pmax==phead)
{
phead=phead->next;
}
else
{
p=phead;
while(p->next != pmax)
{
p=p->next;
}
p->next=pmax->next;
}
pmax->next=NULL;
//加入新链表
if(pnew==NULL)
{
pnew=pmax;
tail=pmax;
}
else
{
tail->next=pmax;
tail=pmax;
}
}
head->next=pnew;
return ;
}
void grade_up(struct stu *head)
{
struct stu *pmax=NULL;
struct stu *p=NULL;
struct stu *phead=head->next;
head->next=NULL;
struct stu *pnew=NULL;
while(phead!=NULL)
{
//找出最大值
pmax=phead;
p=phead;
while(p!=NULL)
{
if(p->grade > pmax->grade)
{
pmax=p;
}
p=p->next;
}
//将其移出
if(pmax==phead)
{
phead=phead->next;
}
else
{
p=phead;
while(p->next != pmax)
{
p=p->next;
}
p->next=pmax->next;
}
pmax->next=NULL;
//加入新链表
pmax->next=pnew;
pnew=pmax;
}
head->next=pnew;
return ;
}
//显示链表,用于测试时使用
void show_list(struct stu *head)
{
if(head==NULL)
{
printf("链表为空!!\n");
return;
}
printf("学号\t姓名\t成绩\n");
struct stu *p=head->next;
while(p!=NULL)
{
printf("%d\t%s\t%d\n",p->id,p->name,p->grade);
p=p->next;
}
printf("\n");
}
/*写文件*/
int write_file(struct stu *head)
{
FILE *fp=NULL;
fp=fopen("./data.txt","wb");
if(fp==NULL)
{
perror("fopen");
return -1;
}
struct stu *p=head->next;
int ret;
while(p!=NULL)
{
ret=fwrite(p,sizeof(struct stu),1,fp);
if(ret<1)
{
perror("fwrite");
fclose(fp);
return -1;
}
p=p->next;
}
fclose(fp);
return 0;
}
/*读文件*/
int read_file(struct stu *head)
{
FILE *fp=NULL;
fp=fopen("./data.txt","rb");
if(fp==NULL)
{
perror("fopen");
return -1;
}
struct stu *pnew=NULL;
int ret;
while(1)
{
pnew=creat_stu();
ret=fread(pnew,sizeof(struct stu),1,fp);
if(ret==0)
{
break;
}
pnew->next=head->next;
head->next=pnew;
}
free(pnew);
fclose(fp);
return 0;
}
2.3 头文件--stu.h
存放函数的头文件
#pragma once
struct stu
{
int id;
char name[32];
int grade;
struct stu *next;
};
/*创建节点*/
struct stu* creat_stu();
/*录入*/
void add_stu(struct stu *head);
/*查找*/
void search_stu(struct stu *head);
struct stu* id_search(struct stu *head);
struct stu* name_search(struct stu *head);
struct stu* grade_search(struct stu *head);
void show_stu(struct stu *p);
/*删除*/
void del_stu(struct stu *head);
void id_del(struct stu *head);
void name_del(struct stu *head);
/*修改*/
void mod_stu(struct stu *head);
void id_mod(struct stu *head);
void name_mod(struct stu *head);
void grade_mod(struct stu *head);
/*显示*/
void display_stu(struct stu *head);
void id_up(struct stu *head);
void grade_down(struct stu *head);
void grade_up(struct stu *head);
void show_list(struct stu *head);
/*写文件*/
int write_file(struct stu *head);
/*读文件*/
int read_file(struct stu *head);