C语言文件写入首行空白及循环异常问题解决咨询
问题分析与解决方案:输入行数后首行空白、有效内容少一行的问题
问题根源
这不是fgets/fputs的特性问题,核心是**scanf读取整数后残留的换行符**在搞事:当你用scanf("%d", &x)输入数字并按下回车时,这个回车字符(\n)会留在标准输入缓冲区里。接下来第一个fgets会直接读取这个换行符,写入文件就成了空白行,剩下的3次fgets才是你手动输入的内容,所以看起来输入4行只写了3行有效内容。
解决方案
给你三种实用的处理方式,按需选择:
方法1:用getchar()吃掉残留换行
在scanf之后加一行代码,专门读取缓冲区里剩下的换行符:
scanf("%d", &x); getchar(); // 吃掉输入数字后的换行符 for (int i = 0; i < x; i++) { fgets(str, sizeof str, stdin); fputs(str, fp); }
适合新手快速解决问题,唯一注意点:如果用户输入数字后还敲了空格再回车,这种方法可能漏处理,但常规场景足够用。
方法2:修改scanf格式串自动跳过空白
让scanf自动匹配数字后的所有空白(包括换行、空格),更鲁棒:
scanf("%d ", &x); // 末尾的空格会匹配任意空白字符 // 或者写成 scanf("%d\n", &x); 效果一致
这种写法不用额外加代码,能处理用户输入数字后各种空白输入的情况。
方法3:全程用fgets读取,再转整数
避免混用scanf和fgets,先读整行输入再转成整数,彻底杜绝缓冲区残留问题:
#include <stdlib.h> // 要用到atoi函数,需要包含这个头文件 // ... 其他代码 ... printf("\nStrings to write:\n"); fgets(str, sizeof str, stdin); x = atoi(str); // 将读取的字符串转成整数 for (int i = 0; i < x; i++) { fgets(str, sizeof str, stdin); fputs(str, fp); }
这种方式输入处理更统一,适合新手养成良好的输入习惯,减少后续类似问题。
额外优化建议
- 打开文件失败后,最好直接
return 1;终止程序,否则后续操作空指针会引发崩溃 - 读取文件时也要判断文件指针是否为
NULL,避免空指针访问
优化后的完整示例代码
#include <stdio.h> #include <stdlib.h> int main() { int x, lc=0; char str[100]; FILE *fp=fopen("test.txt","w"); if (fp==NULL) { printf("\nOpening failed"); return 1; // 打开失败直接退出 } else { printf("\nOpened correctly"); } printf("\nStrings to write:\n"); // 使用方法2的实现 scanf("%d ", &x); for (int i = 0; i < x; i++) { fgets(str, sizeof str, stdin); fputs(str, fp); } fclose(fp); FILE *fr=fopen("test.txt", "r"); if (fr == NULL) { printf("\nRead file failed"); return 1; } while (fgets(str, 100, fr)!=NULL) { lc++; } fclose(fr); printf("\nThere are %d lines", lc); return 0; }
内容的提问来源于stack exchange,提问作者Francesco Lucariello
相关产品推荐
相关产品推荐

