2015-09-04 52 views
3

我一直认为,“在缓冲区‘\ n’”的问题只发生,当我们读取字符, 不过,我在这个问题上用下面的代码绊倒:我们什么时候需要清除scanf缓冲区?

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',则需要清除缓冲区。然后在缓冲区中有一些不能被解释为'int'的字符,例如一个字母。空格(以及开头处的新行)将被忽略。 – mch

+0

请注意,这是**不是**换行符的问题,但无效字符留在'stdin'和'scanf'中,看到它们,失败,重复...... FYI,'%d'跳过前导空白字符。 –

回答

4

一般指导原则是不使用*scanf()用户输入。您从格式错误的输入中正常恢复的能力太有限了,错误出现的可能性太高了(正如SO的绝对数量与*scanf()相关的问题一样)。 *scanf()函数族最适用于只读格式良好的输入(即先前由您自己的应用程序编写的数据)。

无论如何,用户输入是基于行的,至少如果您依赖标准输入功能。

所以使用fgets()来读取一整行输入,然后解析它在内存中。像strtol()strtod()这样的函数可以给出非常具体的反馈,在这一点上它们停止解析,您可以跳过并尝试不同的解析,您可以使用标准的所有string-handling functions来挑选用户的输入。如果事情变成梨形,您可以在错误消息中重复整行输入,在您喜欢的解析尝试中添加任何信息。