C语言使用fscanf()读取fprintf生成的文件为何陷入死循环
问题原因
a+模式打开文件后未偏移到文件开头
a+模式打开文件时,文件指针默认指向文件末尾,直接读取无法获取前面的记录,首次fscanf就会读取失败,后续逻辑完全异常。
feof()的使用逻辑错误
feof()的作用是判断上一次读操作是否触发了EOF,而不是提前预判下一次读操作会不会遇到EOF。你当前的写法是先判断!feof(fp)再执行fscanf,哪怕已经到文件末尾,只要还没执行读操作,feof()都会返回假,会多执行一次无效读取。更严重的是:如果fscanf因为格式不匹配读取失败(没有读到EOF,只是内容和格式串不匹配),文件指针会停在失败的位置,feof()永远不会返回真,直接陷入死循环。
fscanf格式串和实际文件结构不匹配
这是死循环的核心诱因:
- 你用
%15s、%25s读取userID、密码、邮箱,但是%s默认以空白字符(空格、换行等)作为分隔符,你的密码字段里存在空格(比如第四条记录的-a[f !),%s遇到空格就会停止读取,直接导致后续所有字段匹配错位,fscanf返回值小于预期的5个参数,匹配失败后文件指针不再前进,就会一直循环触发匹配失败。 - 格式串末尾的
\n属于空白字符,fscanf里的空白字符会匹配输入中任意数量的空白(包括0个),如果文件最后一行没有换行符,会导致最后一次读取时\n持续尝试匹配后续内容,直到遇到EOF,也可能引发读取异常。
修复方案
- 打开文件后先将指针偏移到文件头:
FILE *fp=fopen(FILENAME(F_PWD),"a+"); if (!fp) { // 原有错误处理逻辑 } fseek(fp, 0, SEEK_SET); // 新增这行,移动指针到文件开头
- 替换循环逻辑,直接判断
fscanf的返回值(fscanf会返回成功匹配的参数个数,只有等于5才代表读取成功,返回EOF代表到达文件末尾):
// 替换原有while(!feof(fp))循环 while(fscanf(fp,F_PWD_FSCANF,&pw_t->id,pw_t->name,pw_t->userID,pw_t->pwd,pw_t->emailID) == 5) { // 原有账号邮箱重复判断逻辑 }
- 调整格式串适配固定长度字段,避免空格导致匹配失败:
因为你所有字段都是固定长度输出,直接按长度读取内容即可,不需要依赖空白分隔,调整宏定义为:
// 按固定长度读取所有字符,兼容字段内的空格 #define F_PWD_FSCANF "%05d%30c%15c%25c%30c"
读取完成后手动截断每个字段末尾的空白字符、补充字符串结束符\0即可。
内容的提问来源于stack exchange,提问作者Anil
相关产品推荐
相关产品推荐

