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
相关产品推荐
相关产品推荐

