fscanf循环读取文件始终重复读取首行的技术求助
问题分析与解决方案
你的问题核心是每次调用pg_read时文件指针意外回到开头,导致只能读取首行。以下是具体排查点和修复方案:
1. 修正pg_read的fscanf判断逻辑
你当前的代码中,if(fscanf(...))的判断逻辑存在问题:fscanf返回的是成功匹配的字段数量,当读取到文件末尾时会返回EOF(值为-1),这会被当作布尔值true进入分支,导致后续stat_read执行错误的文件操作,甚至可能重置文件指针。
修改为判断是否成功读取3个字段:
int pg_read(FILE *fp, pg_t *pgp){ // 仅当成功读取3个字段时才执行后续操作 if(fscanf(fp, "%s %s %s ", pgp->cod, pgp->nome, pgp->classe) == 3){ stat_read(fp, &pgp->b_stat); pgp->equip = equipArray_init(); return 1; } return 0; }
2. 检查stat_read函数的实现
问题大概率出在你未提供的stat_read函数中,需要确认:
- 该函数内没有调用
rewind(fp)或fseek(fp, 0, SEEK_SET)这类重置文件指针的操作; - 该函数内的文件读取逻辑正常,没有因错误处理导致文件指针异常;
- 该函数没有重新打开同一个文件(重复打开会重置指针到开头)。
3. 调试追踪文件指针位置
添加ftell打印来确认每次调用pg_read时指针的位置变化,快速定位问题:
int pg_read(FILE *fp, pg_t *pgp){ // 打印当前指针位置 printf("pg_read start: %ld\n", ftell(fp)); if(fscanf(fp, "%s %s %s ", pgp->cod, pgp->nome, pgp->classe) == 3){ stat_read(fp, &pgp->b_stat); pgp->equip = equipArray_init(); // 打印读取后的指针位置 printf("pg_read end: %ld\n", ftell(fp)); return 1; } printf("pg_read failed, position: %ld\n", ftell(fp)); return 0; }
如果每次pg_read start的位置都是0,说明确实有代码在重置指针,重点排查stat_read和文件打开逻辑。
4. 确认文件打开逻辑
确保文件仅在外部打开一次,使用只读模式"r",而非写入/追加模式:
// 正确的打开方式示例 FILE *fp = fopen("your_file.txt", "r"); if(fp == NULL){ perror("Failed to open file"); return 1; } pgList_read(fp, your_pgList); fclose(fp);
不要在pgList_read或pg_read内部重复打开文件,否则每次打开都会从开头读取。
内容的提问来源于stack exchange,提问作者Gabbo
相关产品推荐
相关产品推荐

