控制台整行读取异常:fgets/scanf语句被跳过的问题排查
你碰到的这个情况太常见了——十有八九是输入缓冲区残留了换行符在搞鬼!
问题根源
假设在调用这个name函数之前,你用了类似scanf("%d", &some_num)或者scanf("%s", some_str)的输入操作:这类scanf只会读取你输入的目标内容(比如整数、不带空格的字符串),但输入时你按下的换行符(\n)会留在输入缓冲区里。等到fgets或者scanf("%[^\n]%*c")执行时,它们一看到缓冲区里的换行符,就会误以为你已经完成输入了,直接跳过了等待你输入的步骤。
几种可行的解决方案
彻底清空缓冲区(推荐)
在调用name函数之前,加入这段代码来清理缓冲区里的所有残留字符,直到遇到换行符或者文件结束:int c; while ((c = getchar()) != '\n' && c != EOF);不管之前的输入留下了什么,这段代码都能把缓冲区清干净,确保后面的
fgets能正常读取你的输入。在之前的scanf里处理换行符
如果你是用scanf读取前面的内容,可以直接在格式串里加%*c来丢弃紧跟目标内容后的换行符。比如原来的scanf("%d", &id)改成:scanf("%d%*c", &id);不过要注意:这种方式只能丢弃一个字符,如果用户输入整数后还敲了其他字符再回车,剩下的字符还是会留在缓冲区里,不如第一种方法彻底。
统一用fgets处理所有输入
放弃混用scanf和fgets,全部用fgets读取输入,再把字符串转换成你需要的类型(比如整数)。比如读取整数可以这么写:char buf[100]; fgets(buf, sizeof(buf), stdin); int num = atoi(buf);这样
fgets会把整行(包括换行符)都读进来,处理完后缓冲区是空的,自然不会有残留问题。
额外提示
用fgets读取的字符串会包含末尾的换行符,如果不需要的话,可以用这个方法去掉:
fgets(k, 100, stdin); // 用strcspn找到换行符的位置,替换成字符串结束符 k[strcspn(k, "\n")] = '\0';
内容的提问来源于stack exchange,提问作者HairyGnome

