原有代码基本不变,只是在代码中加入了文件读取和写入的代码。
文件的读取定义在main.c的代码中,定义一个子函数用来读取文件的内容,如果文件没有创建则直接退出当前子函数,如果文件不为空,就定义新的结点去接收从文件里面读取的数据,然后以链表的方式存储起来,此时就可以让其他的.c文件调用。
#include "main.h"
int main()
{
int num=0;
struct NODE *head=Great_Head();
if(head == NULL)
{
printf("头节点开辟失败\n");
return 0;
}
F_Read(head);
while(1)
{
num=Menu();
switch(num)
{
case add:Stu_Add(head);break;
case del:Stu_Del(head);break;
case chag:Stu_Change(head);break;
case find:Stu_Find(head);break;
case rank:Stu_Rank(head);break;
case print:Stu_Print(head);break;
case insert:Stu_Insert(head);break;
case ret:printf("欢迎下次使用\n");Stu_Fprint(head);return 0;
default:printf("输入有误,重新输入\n");
}
}
return 0;
}
int Menu(void)
{
int num = 0;
printf("1.添加学生信息\n");
printf("2.删除学生信息\n");
printf("3.修改学生信息\n");
printf("4.查找学生信息\n");
printf("5.学生信息排序\n");
printf("6.遍历学生信息\n");
printf("7.插入学生信息\n");
printf("0.退出学生管理系统\n");
printf("请输入要执行的功能的序号\n");
scanf("%d",&num);
getchar();
return num;
}
struct NODE *Great_Head(void)
{
struct NODE *head=(struct NODE *)malloc(sizeof(struct NODE));
if(head == NULL)
{
return NULL;
}
memset(head,0,sizeof(struct Stu));
head->addr=NULL;
return head;
}
//文件读取
void F_Read(struct NODE *head)
{
FILE *fp=fopen("stu.txt","a+");//打开文件,按文件上一次的操作方式打开文件
if(fp==NULL)
{
perror("fopen");//fopen错误原因
return;
}
fscanf(fp,"姓名 学号 成绩\n");
struct NODE *end=head;//定义尾节点
while(fgetc(fp) != EOF)
{
fseek(fp,-1,SEEK_CUR);//将光标从当前位置向前移动一位
struct NODE *new=(struct NODE *)malloc(sizeof(struct NODE));//创建新的节点
fscanf(fp,"%s %d %f\n",new->stu.name,&new->stu.id,&new->stu.score);//从文件中读出姓名、学号、成绩数据存放到新开辟的节点中
new->addr=NULL;//新的节点的指针域为NULL
end->addr=new;//将尾节点的指针域指向新的节点
end=new;//再让新的new节点变成尾节点
}
fclose(fp);
return;
}
文件的写入则是,定义在print.c文件中,定义一个子函数用来向文件写入内容,写入的内容就是刚才通过对学生管理系统的指令操作,比如删除信息、修改信息,修改后的学生信息,同样是以链表的形式存储在计算机空间内,通过函数将链表的内容写入到文件中去保存到文件中,每次操作完程序后,打印学生信息时,文件都是重新被写入新的内容,这样就实现了修改后文件内容的也跟着修改了。
#include "print.h"
void Stu_Print(struct NODE *head)
{
struct NODE *tmp=head->addr;//定义新的tmp接收头节点的地址域
printf("姓名\t学号\t成绩\t\n");
while(tmp!=NULL)//如果tmp的地址域不为NUll,此时的tmp指向下一个节点
{
printf("%s\t%d\t%.1f\t\n",tmp->stu.name,tmp->stu.id,tmp->stu.score);
tmp=tmp->addr;//tmp指向下一个节点
}
return;
}
void Stu_Fprint(struct NODE *head)//将信息输入到stu.txt文件中,每次打开都清空,在输入
{
FILE *fp=fopen("stu.txt","w+");//打开或创建文件
if(fp==NULL)
{
perror("fopen");//错误原因
return;
}
struct NODE *tmp=head->addr;//定义新的tmp接收头节点的地址域
//printf("姓名 学号 成绩\n");
fprintf(fp,"姓名 学号 成绩\n");
while(tmp!=NULL)//如果tmp的地址域不为NUll,此时的tmp指向下一个节点
{
//printf("%-6s%-6d%-6.1f\n",tmp->stu.name,tmp->stu.id,tmp->stu.score);
fprintf(fp,"%-7s %-5d %-6.1f\n",tmp->stu.name,tmp->stu.id,tmp->stu.score);
tmp=tmp->addr;//tmp指向下一个节点
}
fclose(fp);//关闭文件
return;
}