我们什么时候需要清除 scanf 缓冲区? [英] When do we need to clear the scanf buffer?
问题描述
我一直认为'\n' in buffer"的问题只有在我们读取字符时才会出现,但是,我通过以下代码偶然发现了这个问题:
I always thought that the "'\n' in buffer" issue only occurs when we are reading characters, however, I stumbled upon this issue with the following code:
int main(int argc, char** argv){
int height = 0, width = 0;
while(height < 1 || height > 10|| width < 1 || width > 15){
printf("Please insert the height(1~10) and width(1~15) of the parallelogram (integers): ");
if(scanf("%d %d", &height, &width) != 2){
height = width = 0;
}
}
return 0;
}
如上所述,我只用 scanf 读取整数,但是当我输入无效的内容时,这段代码仍然陷入无限循环.如果我清除缓冲区,它就会修复.
As above, I'm only reading integers with scanf, but this piece of code still gets stuck in an infinite loop when I input something invalid. It's fixed if I clear up the buffer.
所以我的问题是,这个'\n' in buffer"问题是一个普遍的问题吗?还是只发生在特殊用途?如果它只发生在特殊用途,是否有一些我需要遵循的一般准则?
So my question is, is this "'\n' in buffer" issue a general thing? Or does it only happen for special usages? If it only happens for special usages, is there some general guideline I need to follow?
推荐答案
一般准则是不要将 *scanf()
用于用户输入.您从格式错误的输入中正常恢复的能力太有限,出错的机会太高(从 SO 上与 *scanf()
相关的大量问题中可以看出).*scanf()
函数系列最适合仅用于读取格式良好的输入(即之前由您自己的应用程序编写的数据).
The general guideline is to not use *scanf()
for user input. Your capabilities to recover gracefully from ill-formatted input are just too limited, the chance of errors too high (as can be seen by the sheer amounts of *scanf()
-related questions here on SO). The *scanf()
function family is best used for reading well-formatted input only (i.e. data that was previously written by your own application).
无论如何,用户输入都是基于行的,至少在您依赖标准输入功能的情况下是这样.
User input is line-based anyway, at least if you're relying on standard input functions.
所以使用fgets()
读取整行输入,然后在内存中解析它.strtol()
或 等函数href="http://en.cppreference.com/w/c/string/byte/strtof" rel="nofollow">strtod()
可以给出非常具体的反馈准确地指出他们停止解析,您可以跳过并尝试不同的解析,您拥有所有 string- 标准的处理功能供您使用,以区分用户的输入.如果事情变成梨形,您可以在错误消息中重复输入的整行,添加您喜欢的有关解析尝试的任何信息.
So use fgets()
to read a full line of input, then parse it in-memory. Functions like strtol()
or strtod()
can give very specific feedback at which point exactly they stopped parsing, you can skip back and try a different parse, you have all the string-handling functions of the standard at your disposal to pick apart your user's input. And if things go pear-shaped, you can repeat the whole line of input in your error message, adding whatever information on your parsing attempts you like.
这篇关于我们什么时候需要清除 scanf 缓冲区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!