C语言使用scanf("%[^\n]")读取字符串出现无限输出问题求解
问题原因分析
- 核心问题出在
scanf("%[^\n]", s)的读取逻辑:该格式符仅匹配到换行符\n之前的内容,不会消费掉输入缓冲区中末尾的换行符。第一次输入结束按下回车后,换行符始终残留在缓冲区中 - 下一轮循环执行
scanf时,遇到缓冲区开头的换行符直接匹配失败,不会更新s数组的内容,也不会修改缓冲区状态,导致循环一直处理上一次读取到的s内容,触发无限重复输出 - 额外还存在两个隐患:一是
%[^\n]未限制读取长度,输入超过256字符时会溢出s数组;二是scanf匹配失败时s内容未初始化,会导致异常输出
修复方案
需要做3处调整即可解决问题:
- 每次读取前自动跳过缓冲区残留的空白字符(包括换行符),同时给格式符加上长度限制避免缓冲区溢出
- 增加
scanf返回值判断,遇到输入结束信号(如用户按下Ctrl+D/Ctrl+Z)时主动退出循环 - 每次过滤输出结束后补充换行符,区分不同次输入的结果
修复后的完整代码
#include <stdio.h> #include <string.h> int main() { while (1) { char s[257]; // 格式串前的空格会自动跳过所有残留空白字符,%256[^\n]限制最多读取256个非换行字符 int ret = scanf(" %256[^\n]", s); // 检测到输入结束时退出循环 if (ret == EOF) break; int len = strlen(s); for (int i=0; i < len; i++){ if( (s[i]>='a'&& s[i]<='z')|| (s[i]>='A' && s[i]<='Z') || (s[i]==' ') ) { printf ("%c",s[i]); } } // 输出完成补换行,让结果可读性更好 printf("\n"); } return 0; }
内容的提问来源于stack exchange,提问作者Sadu_007
相关产品推荐
相关产品推荐

