求大神帮忙看下,链表数据可实现存贮,读取时出错。
程序代码:#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "windows.h" //程序休眠
void menu(struct student *head); //主菜单页面:选择进行何种操作
void show(struct student *head); //显示学生信息
struct student *insert(struct student *head); //增加每个学生的信息
void revise(struct student *head); //修改学生的信息
struct student *deleted(struct student *head); //删除学生信息
void inquiry(struct student *head); //查询学生信息
struct student *read(); //读取文件中的数据
void insertNode(struct student *head,struct student *newNode);
void save(struct student *head); //将链表中数据存入文档
#define LEN sizeof(struct student)
typedef struct student
{
char num[20]; //学号
char name[20]; //姓名
char sex; //性别
float score; //成绩
struct student *next; //指向下一个节点
};
void menu(struct student *head) //主菜单页面:选择进行何种操作.
{
struct student *p;
int a;
// file(head); //创建 学生管理系统 的text文件夹
for(;;)
{
system("cls"); //清屏
printf("\n 请选择操作:");
printf("\n ==================================================");
printf("\n\n (1)显示 学生信息 (2)增加 学生信息");
printf("\n\n (3)修改 学生信息 (4)删除 学生信息");
printf("\n\n (5)查询 学生信息 (6)保存 学生信息");
printf("\n\n (0)退出程序 (会自动保存学生信息)");
printf("\n\n ==================================================");
printf("\n\n 你的选择是: ");
scanf("%d",&a);
switch(a)
{
case 1: show(head);break; //显示学生信息
case 2: p=insert(head);break; //增加学生的信息
case 3: revise(head);break; //修改学生的信息
case 4: deleted(head);break; //删除学生信息
case 5: inquiry(head);break; //查询学生信息
case 6: save(head);break; //保存链表数据
case 0: save(head);exit(0); //保存链表数据,退出程序
default :break;
}
}
}
void show(struct student *head) //显示学生信息
{
struct student *p;
p=head;
system("cls"); //清屏
if(head==NULL)
printf("\n 无学生的信息!!");
else
{
printf("\n 现有学生信息如下:");
printf("\n\n 学号 姓名 性别 成绩");
printf("\n\n ==================================================\n");
while(p!=NULL)
{
printf("\n %s %s %c %3.2f",p->num,p->name,p->sex,p->score);
p=p->next;
}
printf("\n\n ==================================================");
}
printf("\n\n ");
system("pause"); //按任意键继续
}
struct student *insert(struct student *head) //增加每个学生的信息
{
char *strName="学生成绩管理系统.txt";
struct student *q1,*q2,*q,*p,*r;
char b,*c;
int a;
system("cls"); //清屏
q2=NULL; //创建第一个附加头结点
q1=head;
r=head;
printf("\n 请输入新增学生的信息:");
printf("\n\n =======================================================\n");
p=(struct student *)malloc(sizeof(struct student)); //动态分配节点存储空间
for(;;)
{
printf("\n >> 学号 (最多允许12个字符,输入 0 退出): ");
scanf("%s",p->num); //输入学生学号
c=p->num;
if(c[0]=='0')
if(c[1]=='\0')
menu(head); //退出此函数,返回主菜单
while(r!=NULL)
{
if(strcmp(r->num,p->num)==0)
{
a=1;
break;
}
else
r=r->next;
}
if(a==1)
{
a=0;
printf("\n 此学号已存在,请从新输入.\n");
}
else if(strlen(p->num)>12)
printf("\n >> 输入有误,请重新输入\n");
else
break;
}
for(;;)
{
printf("\n >> 姓名 (最多允许10个字符): ");
scanf("%s",p->name); //学生姓名
if(strlen(p->name)>10)
printf(" >> 输入有误,请重新输入\n");
else
break;
}
printf("\n >> 性别 (M:男,F:女): ");
scanf("%s",&p->sex); //性别
for(;;)
{
printf("\n >> 成绩 (100以内的数,允许小数): ");
scanf("%f",&p->score); //成绩
if(p->score<=0&&p->score>100)
printf("\n >> 输入有误,请重新输入\n");
else
break;
}
while(q1!=NULL&&q1->num<p->num)
{
q2=q1; //移动q1,q2
q1=q1->next;
}
if(q2==NULL) //表示在表头结点之前插入节点
{
p->next=q1;
head=p;
}
else //在非表首插入结点
{
p->next=q1;
q2->next=p;
}
printf("\n\n =======================================================");
printf("\n\n 继续输入?(Y/N): ");
for(;;)
{
scanf("%c",&b);
if(b=='Y'||b=='y')
{
q=insert(head); //增加每个学生的信息
break;
}
else if(b=='N'||b=='n')
{
menu(head); //主菜单页面:选择进行何种操作.
break;
}
}
// WriteLinklistToFile(strName,head);
return head; //返回链表的第一个结点的地址
}
void revise(struct student *head) //修改学生的信息
{
char *strName="学生成绩管理系统.txt";
struct student *q1,*q2;
char a[20]; //学号
q2=NULL;
q1=head;
system("cls"); //清屏
printf("\n 请输入要修改学生的学号(输入 0 退出): ");
scanf("%s",a);
if(a[0]=='0')
if(a[1]=='\0')
menu(head); //退出此函数,返回主菜单
while(q1!=NULL&&strcmp(q1->num,a)!=0)
{
q2=q1;
q1=q1->next;
}
if(q1==NULL)
printf("\n\n 没有符合条件学生的信息!!!!!");
else
{
printf("\n 此学生信息为:");
printf("\n\n %s %s %c %3.2f",q1->num,q1->name,q1->sex,q1->score);
printf("\n\n\n >> 学号 (不可更改): %s",q1->num);
for(;;)
{
printf("\n >> 此学生原姓名为: %s",q1->name);
printf("\n >> 姓名 (最多允许10个字符): ");
scanf("%s",q1->name); //学生姓名
if(strlen(q1->name)>10)
printf(" >> 输入有误,请重新输入\n");
else
break;
}
printf("\n >> 此学生原性别为: %c",q1->sex);
printf("\n >> 性别 (M:男,F:女): ");
scanf("%s",&q1->sex); //性别
for(;;)
{
printf("\n >> 此学生原成绩为: %3.2f",q1->score);
printf("\n >> 成绩 (100以内的数,允许小数): ");
scanf("%f",&q1->score); //成绩
if(q1->score<=0&&q1->score>100)
printf("\n >> 输入有误,请重新输入\n");
else
{
printf("\n\n 更新此学生信息成功!");
break;
}
}
}
printf("\n\n ==================================================");
printf("\n\n ");
system("pause"); //按任意键继续
}
struct student *deleted(struct student *head) //删除学生信息
{
char *strName="学生成绩管理系统.txt";
struct student *q1,*q2,*p;
char b;
char a[20];
q2=NULL;
q1=head;
p=head;
system("cls"); //清屏
printf("\n\n ==================================================");
printf("\n\n 请输入你要删除学生的学号(输入 0 退出): ");
scanf("%s",a);
if(a[0]=='0')
if(a[1]=='\0')
menu(head); //退出此函数,返回主菜单
while(p!=NULL&&strcmp(p->num,a)!=0)
p=p->next;
if(p==NULL)
printf("\n\n 没有任何学生信息!\n");
else
{
printf("\n\n 学号 姓名 性别 成绩");
printf("\n\n %s %s %c %3.2f",q1->num,q1->name,q1->sex,q1->score);
printf("\n\n 你确定要删除此学生的信息?(Y/N): ");
for(;;)
{
scanf("%c",&b);
if(b=='Y'||b=='y')
{
while(q1!=NULL&&strcmp(q1->num,a)!=0)
{
q2=q1;
q1=q1->next;
}
if(q2==NULL)
head=head->next;
else if(q1!=NULL)
q2->next=q1->next;
free(q1);
printf("\n\n 删除此学生信息成功!");
break;
}
else if(b=='N'||b=='n')
{
menu(head); //主菜单页面:选择进行何种操作.
break;
}
}
}
printf("\n\n ==================================================");
printf("\n\n ");
system("pause"); //按任意键继续
return head;
}
void inquiry(struct student *head) //查询学生信息
{
struct student *q1;
char a[20];
q1=head;
system("cls"); //清屏
printf("\n\n ==================================================");
printf("\n\n 请输入你要查询学生的学号: ");
scanf("%s",a);
while(q1!=NULL&&strcmp(q1->num,a)!=0)
q1=q1->next;
if(q1==NULL)
printf("\n 没有此学生的信息!!!");
else
{
printf("\n\n 学号 姓名 性别 成绩");
printf("\n %s %s %c %3.2f",q1->num,q1->name,q1->sex,q1->score);
}
printf("\n\n ==================================================");
printf("\n\n ");
system("pause"); //按任意键继续
}
struct student *read() //读取文件中的数据
{
FILE *fp;
struct student *f,*head=NULL; //指针要习惯给它赋初值NULL,不要形成空指针
char str[512];
if((fp=fopen("学生成绩管理系统.txt","r+"))==NULL)
{
printf("\n\n 打开文件失败!!\n");
return head; //此时head is NULL
}
if( fgets( str , sizeof(str) , fp ) == NULL )
{
printf("\n\n 文件中没有数据!\n");
fclose(fp);
return head; //此时head is NULL
}
//有数据再创建链表,不要创建空表
head=(struct student *)malloc(LEN);
if(head==NULL)
{
printf("\n\n 分配内存失败!\n");
fclose(fp);
exit(0);
}
head->next=NULL;
sscanf(str,"%s %s %s %d",head->num,head->name,head->sex,head->score) ;
while (fgets( str , sizeof(str) , fp ) != NULL)
{
f=(struct student *)malloc(LEN);
f->next=NULL;
sscanf(str,"%s %s %s %d",f->num,f->name,f->sex,f->score) ;
insertNode(head,f);
}
fclose(fp);
return head;
}
void insertNode(struct student *head,struct student *newNode)
{
struct student *f;
f=head;
while(f->next!=NULL)
f=f->next;
f->next=newNode;
newNode->next=NULL;
}
void save(struct student *head) //将链表中的数据存入文档中
{
struct student *p;
FILE *f;
p=head;
system("cls"); //清屏
if(p!=NULL)
{
f=fopen("学生成绩管理系统.txt","w+");
do
{
fprintf(f,"%-16s%-21s%-11c%-5.2f\n",p->num,p->name,p->sex,p->score);
p=p->next;
}while(p!=NULL);
fclose(f);
}
printf("\n\n 保存信息成功!!!");
Sleep(1000); //程序休眠几秒钟
}
void main()
{
struct student *head; //对每个商品数据定义为结构体
head=read(); //读取文件的数据
menu(head); //主菜单页面:选择进行何种操作.
}









