You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 06:17:33