c语言学生管理系统,保存和读取文件模块有错误,写在txt中的正常,但是读出来就有问题了

在文档中 是 : 1 2 3 4 5 6 7 8
a b c d e f g h 一切正常,但是读入给链表就出问题了
求大神帮忙看下我的错哪里了,下面是数据保存模块和数据读入(从文件中)模块

//保存到文件void save(){ FILE *fp; struct student *p; p = head; if( (fp = fopen("student.txt","w+")) == NULL ) { printf("打开失败!\n"); } else { while( p != NULL ) { fprintf(fp,"%s %s %s %s %s %s %s %s",p->student_id,p->student_id,p->name,p->age,p->gender,p->born,p->address,p->number,p->E_mail); fprintf(fp,"\n"); p = p->next; }
} fclose(fp); printf("文件保存成功!\n\n"); return ;}
//打开文件信息void open(){ FILE *fp = NULL; struct student *p1,*p2; head = p1 = p2 = (struct student *)malloc(sizeof(struct student)); fp = fopen( "student.txt","r"); if( fp== NULL ) { printf("该文件没有任何信息记录!\n"); return ; } head = p1; p1 ->next = p2; while(fgetc(fp) != EOF ) { fflush(stdin); fscanf(fp,"%s %s %s %s %s %s %s %s",&p2->student_id,&p2->name,&p2->age,&p2->gender,&p2->born,&p2->address,&p2->number,&p2->E_mail); // printf("\n"); p1 = p2; p2 = (struct student *)malloc(sizeof(struct student)); p1 ->next = p2; } p1 ->next = NULL; free(p2); fclose(fp); printf("成功打开文件!\n"); return;}

你的open()函数有几个问题,其中1和2是你的问题的主要原因。

1. 作为while循环判断条件的fgetc()函数从文件流读取了一个字符,移动了文件流的读取指针,导致文件数据并没有全部由fscanf()函数读取。

2. 没有判断fscanf()函数的返回值,如果出现读取失败、读不全8项数据等情况,仍然认为数据是有效的。

3. 如果打开文件失败,一开始分配的内存没有释放。

4. 如果打开文件成功但文件为空(while循环体一次都没有执行),一开始分配的内存释放了,但head还是指向这个已经释放的内存空间。

5. 估计你的struct student里各个成员变量是字符数组,如果是这样的话,fscanf()函数里引用这些成员变量时不需要加'&'。(但这个只是个warning,不是error)。

 

试试这个open()函数。

void open()
{
FILE *fp;
struct student *p1, *p2;
int ret;
/* 读取文件前先把链表头设为NULL,表示链表为空 */
head = NULL;
/* 尝试打开文件 */
fp = fopen("student.txt", "r");
if (fp == NULL)
{
printf("打开文件失败!\n");
return;
}
/* p1指向链表最后一个有效的元素,目前为NULL */
p1 = NULL;
/* 为链表第一个元素分配内存,并把链表头指向该元素 */
head = p2 = (struct student *)malloc(sizeof(struct student));
while (1)
{
ret = fscanf(fp, "%s %s %s %s %s %s %s %s",
p2->student_id, p2->name, p2->age, p2->gender,
p2->born, p2->address, p2->number, p2->E_mail);
/* 如果fscanf()没有读取8项数据,就认为是失败 */
if (ret != 8)
{
/* 如果这是链表第一个元素,则把链表头设为NULL */
if (head == p2)
head = NULL;
/* 如果前一个元素非空,则把它的next指针设为NULL,表示链表结束 */
if (p1 != NULL)
p1->next = NULL;
/* 释放当前元素的内存 */
free(p2);
/* 退出循环 */
break;
}
/* p1指向链表最后一个有效的元素 */
p1 = p2;
/* 为下一个元素分配内存 */
p2 = (struct student *)malloc(sizeof(struct student));
p1->next = p2;
}
fclose(fp);
printf("成功打开文件!\n");
}

温馨提示:答案为网友推荐,仅供参考
相似回答