使用fflush(stdin)
有什么区别
和flushstdin()
?我知道的唯一区别是我需要在使用flushstdin()
之前写出那些无效的东西,但我不知道为什么。
void flushstdin()
{
int c;
while((c = getchar()) != '\n' && c != EOF);
}
int main () {
float a, b, c;
float s=0, ar1=0, ar2=0;
printf("Inform value of side A");
while(scanf("%f",&a) != 1 || a <= 0){
printf("Invalid value.\n");
flushstdin();
}
}
和
int main(){
float a,b,c,s=0;
printf("Inform value of side A.");
while(scanf("%f",&a) != 1 || a<=0){
printf("Invalid value.\n");
fflush(stdin);
}
}
我是初学者!哪个代码最好?或者他们是平等的?
答案 0 :(得分:8)
区别在于flushstdin
是用户定义的,是标准C中唯一可以刷新stdin
的方式。
fflush
是标准库函数。 fflush(stdin);
将调用未定义的行为。
fflush
仅针对输出流进行定义。由于它定义了&#34; flush&#34;是完成缓冲字符的写入(不丢弃它们),丢弃未读输入对输入流上的fflush
不是类似的意思。
没有标准方法可以从stdio输入流中丢弃未读字符。 有些供应商会实施
fflush
,以便fflush(stdin)
丢弃未读的字符,但便携式程序不能依赖于此。 (某些版本的stdio
库实现了fpurge
或fabort
调用,它们执行相同的操作,但这些调用也不是标准的。)另请注意,刷新{{ 1}}输入缓冲区不一定足够:未读字符也可以在其他OS级输入缓冲区中累积。如果您试图主动放弃输入(可能是因为预期会发出意外提示来确认破坏性行为,而意外打字并且可能会造成灾难性后果),您可能会必须使用特定于系统的技术来检测预先输入类型的输入;见问题19.1和19.2。请记住,如果丢弃输入错误的输入,用户可能会感到沮丧。
答案 1 :(得分:2)
他们完全不同。他们都可以&#34;冲洗&#34;输入,但在不同的意义上。
fflush
是标准的C函数。它在stdin
等输入流上的行为是 undefined - 这意味着C标准没有定义它的行为。
某些系统确实在输入流上定义fflush
的行为。例如在Linux上:
对于输入流,
fflush()
会丢弃已经存在的所有缓冲数据 从底层文件中获取,但尚未被使用 应用
如果您的程序在基于Linux的系统上运行,或者在另一个记录相同行为的系统上运行,则可以依赖fflush(stdin)
按照此说明行事。您的程序行为将无法移植;在其他系统上,它可能会以任意不好的方式运行。 (如果fflush(stdin)
不起作用,很可能除了返回错误指示之外什么都不做,但这不能保证。)
您自己的flushstdin
函数与fflush(stdin)
的Linux行为有所不同。它会读取并丢弃直到第一个换行符或直到EOF
(由文件结尾或错误触发)的所有输入函数。无论该输入是否被缓冲,它都会这样做。
例如,假设您输入字符hello
(没有换行符),然后您的程序调用{{1}},然后您输入换行符。
fflush(stdin)
,鉴于Linux记录的行为,将丢弃fflush(stdin)
并立即返回,让新行在稍后的调用中被读取。它&#34;冲洗&#34; hello
在某种意义上它会丢弃所有待处理的输入,无论它是什么。
您的stdin
函数将读取并放弃flushstdin()
,然后等到键入 Enter (或 Ctrl-D ),然后阅读并丢弃。它会读取并丢弃所有输入到换行符或EOF,无论它是否在通话时等待。
同样,hello
的行为不是由C标准定义的,因此使用它会使您的程序不可移植(并且您的编译器不一定会警告您)。
顺便说一下,&#34;那无效的东西&#34;是fflush(stdin)
函数的定义。 flushstdin
不需要它,因为它是已经为您定义的标准C库函数。
答案 2 :(得分:1)
两个版本都有问题。
正如已经广泛记载的那样,fflush(stdin)
根据C标准具有未定义的行为。使用flushstdin()
函数的替代方案并没有好多少。我建议一次读取一行标准输入并使用sscanf()
解析它,所有这些都可以根据需要使用实用程序函数:
int readfloat(const char *prompt, float *val) {
char buf[128];
for (;;) {
if (prompt)
fputs(prompt, stdout);
if (!fgets(buf, sizeof(buf), stdin)) {
printf("Premature end of file\n");
return 1;
}
if (sscanf(buf, "%f", val) == 1 && *val > 0)
return 0;
printf("Invalid value.\n");
}
}
int main(void) {
float a, b, c, s = 0;
if (readfloat("Enter value of side A: ", &a))
return 1;
...
}