何时需要清除scanf缓冲区?

5
我一直以为“缓冲区中的‘\n’”问题只会在读取字符时出现, 然而,我在以下代码中遇到了这个问题:
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读取整数,但是当我输入无效内容时,这段代码仍然会陷入无限循环。 如果我清理缓冲区,问题就解决了。

所以我的问题是,这个“缓冲区中存在'\n'”的问题是普遍存在的吗? 还是只发生在特殊情况下?如果它只发生在特殊情况下,是否有一些一般性的指导方针需要遵循?


3
如果 scanf 没有返回 2,则需要清除缓冲区。这时,缓冲区中有一些内容无法被解释为一个整数,比如一个字母。空格(以及开头的换行符)将会被忽略。 - mch
请注意,这不是换行符的问题,而是无效字符停留在stdinscanf中,发现它们失败,重复... FYI,%d会跳过前导空格字符。 - Spikatrix
1个回答

6
一般指南是不要使用*scanf()来处理用户输入。您从不正确格式的输入中恢复的能力非常有限,错误的概率太高(可以从此处看到大量*scanf()相关的问题)。 *scanf()函数族最好只用于读取格式正确的输入(即先前由您自己的应用程序编写的数据)。
无论如何,用户输入都是基于行的,至少如果您依赖标准输入函数的话。
因此,使用fgets()来读取完整的一行输入,然后在内存中解析它。像strtol()strtod()这样的函数可以给出非常具体的反馈,以确定它们停止解析的确切位置,您可以跳过并尝试不同的解析,您可以利用标准库中提供的所有字符串处理函数拆分用户的输入。如果事情被搞砸了,您可以在错误消息中重复整行输入,并添加您喜欢的有关解析尝试的任何信息。

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