求大神帮忙看下,链表数据可实现存贮,读取时出错。
程序代码:
#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); //主菜单页面:选择进行何种操作. }