You need to enable JavaScript to run this app. C语言fprintf写文件后fscanf读数据无法正常显示的问题排查
优惠活动
大模型
产品
解决方案
定价
更多

C语言fprintf写文件后fscanf读数据无法正常显示的问题排查

代码读写流程失效的核心原因

问题根源拆解

  • 文件指针位置未复位
    你用w+模式打开文件后,先执行完整个写入循环把2条学生数据落盘,此时文件的读写指针已经移动到整个文件的最末尾。直接进入读取循环执行fscanf时,是从文件末尾位置开始扫描,没有任何有效数据可读,自然输出的全是无效乱值。
    你测试时移除fscanf逻辑、写入功能就正常的现象,刚好可以对应这个问题——写入完成后指针的位置,根本不影响已经写到磁盘上的文件内容。

  • 写入内容缺少读取边界
    当前fprintf使用的格式串"%s%d%d"没有添加任何空格、换行这类分隔符,所有字段会被直接拼接成无间隔的长字符串。举个实际的写入效果例子:
    若输入第一个学生姓名为Tom、学号1、入学年份2022,第二个学生姓名为Jack、学号2、入学年份2023,最终写入student.txt的内容会是Tom12022Jack22023。
    哪怕把文件指针复位到开头,后续用fscanf搭配%s %d %d读取时,%s的规则是碰到空白字符才停止读取,它会一口气把整串无间隔的内容全塞进姓名数组,根本没法拆分出后面的学号和年份,后续的数字读取会全部失败。

具体修正方案

  • 修改写入的格式串,给字段之间加空格,每条记录写完换行做分隔,将原写入逻辑fprintf(ptr,"%s%d%d",s[i].name,s[i].rollNo,s[i].intakeYear);替换为fprintf(ptr, "%s %d %d\n", s[i].name, s[i].rollNo, s[i].intakeYear);,让写进文件的内容有明确的解析边界,和fscanf的读取规则匹配。
  • 在写入循环全部执行完成、开始读取循环之前,添加一句rewind(ptr);,强制把文件指针拉回文件起始位置,确保读取操作从文件头开始扫描。
  • 代码规范化调整:将结构体成员定义拆分为单独行,把int rollNo,intakeYear;改成int rollNo; int intakeYear;,避免后续维护出现歧义。
  • 健壮性优化:每次调用fscanf后判断返回值是否为3(代表姓名、学号、入学年份三个字段都读取成功),避免文件内容异常时输出无意义的乱值。

修正后的核心逻辑片段参考:

// 原有输入逻辑不变
for(int i = 0 ; i < 2 ; i++)
{
    printf("Enter the name of student\n");
    scanf("%s",s[i].name);
    printf("Enter the roll number\n");
    scanf("%d",&s[i].rollNo);
    printf("Enter the  intakeYear\n");
    scanf("%d",&s[i].intakeYear);
    // 修正后的写入格式
    fprintf(ptr, "%s %d %d\n", s[i].name, s[i].rollNo, s[i].intakeYear);
}

// 新增:复位文件指针
rewind(ptr);

// 原有读取逻辑即可正常运行
for(int i = 0 ; i < 2 ; i++)
{
    fscanf(ptr,"%s%d%d",s[i].name,&s[i].rollNo,&s[i].intakeYear);
    printf("Name:%s",s[i].name);
    printf("Roll:%d\n",s[i].rollNo);
    printf("Intake Year:%d\n",s[i].intakeYear);
}

内容的提问来源于stack exchange,提问作者IcanCode

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 12:54:04