使用fscanf()读取文件到链表时,变量均为空或0的问题求助
问题分析与解决方案
核心原因:文件指针位置错误
你的代码中readSize函数会遍历整个文件统计行数,这会将文件指针移动到文件末尾(EOF)。后续调用fscanf时,指针已经处于末尾,没有数据可读,导致结构体中的字段始终处于未正确赋值的状态(表现为空字符串或0)。
修复方案
方案1:重置文件指针到开头
在统计行数后,调用rewind(fp)或fseek(fp, 0, SEEK_SET)将文件指针移回文件起始位置,让fscanf能正常读取数据。修改后的readFile函数如下:
int readFile(char *file, struct profile** head) { FILE *fp = fopen(file, "r"); if (fp == NULL) return ERR; int lines = readSize(fp); // 重置文件指针到文件开头 rewind(fp); struct profile *curr, *prev; curr = prev = NULL; for (int i=0; i<lines; i++) { curr = malloc(sizeof(struct profile)); // 检查内存分配是否成功 if (curr == NULL) { fclose(fp); return ERR; } // 检查fscanf是否成功读取4个字段 int ret = fscanf(fp, "%s%s%d%d", curr->name, curr->lname, &curr->weight, &curr->height); if (ret != 4) { free(curr); fclose(fp); return ERR; } curr->next = NULL; if (i == 0) *head = curr; else prev->next = curr; prev = curr; } fclose(fp); return OK; }
方案2:无需提前统计行数(更高效)
没必要先遍历文件统计行数,直接循环读取直到fscanf返回EOF(文件末尾)即可,这样能避免两次遍历文件,提升效率。修改后的readFile函数如下:
int readFile(char *file, struct profile** head) { FILE *fp = fopen(file, "r"); if (fp == NULL) return ERR; struct profile *curr, *prev = NULL; *head = NULL; while (1) { curr = malloc(sizeof(struct profile)); if (curr == NULL) { // 内存分配失败,清理已分配节点避免泄漏 freeNode(head); fclose(fp); return ERR; } // 尝试读取一组数据 int ret = fscanf(fp, "%s%s%d%d", curr->name, curr->lname, &curr->weight, &curr->height); if (ret == EOF) { // 到达文件末尾,释放当前空节点 free(curr); break; } if (ret != 4) { // 数据格式错误,清理资源 free(curr); freeNode(head); fclose(fp); return ERR; } curr->next = NULL; if (*head == NULL) { *head = curr; } else { prev->next = curr; } prev = curr; } fclose(fp); return OK; }
使用该方案可以直接删除readSize函数。
其他优化点
- 内存分配检查:必须检查
malloc的返回值,避免内存不足导致程序崩溃。 - 读取结果校验:每次调用
fscanf后检查返回值,确保成功读取预期的4个字段,避免格式错误导致的垃圾数据。 - 内存泄漏修复:在读取过程中发生错误时,要释放已分配的节点,避免内存泄漏。
- freeNode函数修正:原函数中
head = NULL;仅修改了局部指针,不会影响外部变量,应改为*head = NULL;:
void freeNode(struct profile** head) { struct profile* curr = *head; while (curr != NULL) { struct profile* next = curr->next; free(curr); curr = next; } *head = NULL; // 修正此处 }
内容的提问来源于stack exchange,提问作者sansarc
相关产品推荐
相关产品推荐

