2014-11-22 109 views
0

我正在使用我创建的宏来清除scanf后的缓冲区,但我被告知这不是一个好主意,因为“很多原因”。你能解释一下为什么以及如何清理它?我知道使用fflush(stdin)是一个非常糟糕的主意,因为它没有被定义。使用C中的宏清除缓冲区是不是一个好主意?

这是我用的宏:

#define CLEAR_BUFFER do { c = getchar(); } while (c != '\n' && c != EOF); 

而且也,另一个问题:在“现实世界”中使用scanf函数?如果是的话,人们如何清理缓冲区?

感谢

+0

如果您在阅读某些内容后遇到空格或换行符问题,可以在'%d','%f'或类似内容之前放置一个空格,例如, 'scanf(“%d”,x)' – humodz 2014-11-22 13:24:59

+0

对于用户输入,使用'fgets()'来获取数据并很好地处理线路缓冲输入流。 – pmg 2014-11-22 13:32:42

+1

@ pmg为健壮的代码,fgets也需要清理,因为行可能会超过缓冲区大小 – 2014-11-22 14:00:14

回答

7

的想法是好的,虽然执行还有待改进:

#define CLEAR_BUFFER() do { int ch; while ((ch = getchar()) != EOF && ch != '\n') {} } while (0) 

你的版本没有申报c并能正确使用。如果你不熟悉do...while(0)see here

甚至比这两个更好的方式是编写一个函数:

void clear_buffer(void) 
{ 
    int ch; while ((ch = getchar()) != EOF && ch != '\n') {} 
} 

如果你有兴趣来区分EOL是否发生或出现了错误,您能做出这样的回报bool(但调用代码无论如何可以检查feof(stdin) || ferror(stdin))。

在C99中,这可能是内联函数,但如果您在C90中并使其非内联,那么这不是一个大问题。


对于问题的第二部分:我从来没有使用scanf,我在清理我刚才所描述的方式缓冲。其他人可能会以不同的方式做到这一点,这更多的是个人偏好问题。

+0

我宁愿'clear_buffer()'return'ch' ...以便调用代码可以很容易地检测到'EOF'。 – pmg 2014-11-22 13:29:11

+0

在获取所需输入之后使用'%* c'敲掉换行符是不是一个好主意? – Gopi 2014-11-22 13:33:00

+0

我更喜欢原来的'do while'方法,对我来说似乎更具可读性。 – 2014-11-22 13:33:23