理解"while (getchar() != '\n')"

3

我希望能更好地理解这个命令的背后原理。

一开始,我试图防止我的应用在scanf()接收到char而不是期望的int时失败。提供给我的解决方案是添加一行代码while (getchar() != '\n');以清除输入缓冲区。并且它奏效了,太棒了!

但由于我使用的是scanf()而不是getchar(),所以我觉得有点困惑,因为我需要使用完全不同的命令来清除缓冲区。

我已经谷歌了一下,从我所了解的情况来看,getchar()使用的是stdin,这就是使用该命令清除缓冲区的缓冲区。这也意味着,在这种情况下,scanf()也在使用stdin

这个假设是正确的吗?


4
顺便提一下,使用 while(getchar() != '\n'); 并不是很好的做法,因为如果出现文件末尾(例如用户按Ctrl-D或被重定向到stdin的文件已结束)或其他错误,它将无限循环(getchar() 永远返回 EOF,并且您的循环永远不会结束)。通常你需要像这样写int ch; while((ch = getchar()) != EOF && ch != '\n'); - Matteo Italia
你也可以使用 scanf("%*[^\n]"); scanf("%*c"); - Spikatrix
1
这些都在文档中有详细说明:scanf()getch() - alk
不要使用 scanf() 进行用户输入。 - pmg
2个回答

2
是的,确实如此。文档中明确提到了这一点。
引用《C11》标准,第§7.21.6.2章节:
“函数fscanf从指向流的指针stream读取输入,受字符串格式控制,该字符串指定可接受的输入序列以及如何将它们转换为赋值所使用的对象,并使用后续参数作为指向接收转换后输入的对象的指针。[....]”
和第§7.21.6.4章节:
“函数scanf等效于在参数列表前插入stdin参数的函数fscanf。”
只是为了补充一下为什么你需要使用getchar()来清除scanf()也从stdin读取的内容: scanf()只有在匹配成功时才会从输入缓冲区中读取,这由指定可接受输入序列的格式指针所确定。如果匹配失败(例如,用户使用%d转换说明符时提供了char),则缓冲区中的输入将保持未读状态,并且可以被下一次调用scanf()读取。
因此,在调用scanf()时,建议始终检查失败并使用getchar()清除缓冲区。getchar()逐个字符地读取stdin,并在每次调用时将读取的字符作为int类型的unsigned char强制转换返回,从而消耗缓冲区中的任何输入并清除它。

1
我已经谷歌了一下,据我所知,'getchar()'使用的是'stdin',这就是该命令清除缓冲区的原因。这也意味着在这种情况下'scanf'也使用'stdin'。这个假设是正确的吗?
是的,这是正确的。
根据文档(我强调),[scanf]从'stdin'读取数据,并根据参数格式将它们存储到附加参数指向的位置中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接