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

2024-12-18 15:55:20
推荐回答(1个)
回答1:

你的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");
}