使用fflush(stdin)
的区别是什么和flushstdin()
?我所知道的唯一区别是,我需要在使用flushstdin()
之前写那个void的东西,但我不知道为什么。
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);
}
}
我是初学者!哪个代码是最好的?或者它们是相等的?
区别在于flushstdin
是用户定义的,并且是标准C中冲洗stdin
的唯一方法。fflush
是一个标准库函数。fflush(stdin);
将调用未定义的行为。
c- faq: 12.26a:
fflush
仅为输出流定义。由于它对"flush"的定义是完成对缓冲字符的写入(而不是丢弃它们),因此丢弃未读输入在输入流上的fflush
不会有类似的含义。
c-faq: 12.26b:
没有标准的方法从演播室输入流中丢弃未读字符。一些供应商确实实现了
fflush
,以便fflush(stdin)
丢弃未读字符,尽管可移植程序不能依赖于此。(stdio
库的一些版本实现了fpurge
或fabort
调用,它们做同样的事情,但这些也不是标准的。)还要注意,刷新stdio
输入缓冲区并不一定足够:未读字符也可以累积在其他操作系统级输入缓冲区中。如果您试图主动丢弃输入(可能是预期发出一个意外提示来确认破坏性操作,对于这种情况,不小心键入的"y"可能是灾难性的),则必须使用特定于系统的技术来检测是否存在提前键入的输入;见问题19.1和19.2。请记住,如果您丢弃碰巧输入得太快的输入,用户可能会感到沮丧。
它们完全不同。它们都可以"刷新"输入,但含义不同。
fflush
是标准的C函数。它在输入流(如stdin
)上的行为undefined——这意味着C标准没有定义它的行为。
一些系统确实定义了fflush
在输入流上的行为。例如在Linux上:
对于输入流,
fflush()
将丢弃所有已缓存的数据从基础文件中获取,但尚未被应用程序。
如果您的程序运行在基于linux的系统上,或者在另一个记录相同行为的系统上,您可以依赖fflush(stdin)
按照此描述行事。你的程序的行为将不能移植;在其他系统上,它可能以任意糟糕的方式运行。(最有可能的是,如果fflush(stdin)
不工作,它除了返回错误指示外什么也不做,但不能保证。)
您自己的flushstdin
函数与fflush(stdin)
的Linux行为有所不同。它读取并丢弃所有输入函数,直到第一个换行符或直到EOF
(由文件结束符或错误触发)。不管输入是否被缓冲,它都会这样做。
hello
(没有换行符),那么您的程序调用fflush(stdin)
, ,然后您输入换行符。 fflush(stdin)
,给定Linux文档的行为,将丢弃hello
并立即返回,留下换行符供稍后的调用读取。它"刷新"stdin
的意思是,它丢弃所有挂起的输入,不管它是什么。
您的flushstdin()
函数将读取并丢弃hello
,然后等待,直到您键入输入(或Ctrl-D),然后读取并丢弃它。它读取并丢弃除换行符或EOF之外的所有输入,而不管调用时它是否挂起。
并且,fflush(stdin)
的行为不是由C标准定义的,所以使用它会使您的程序不可移植(并且您的编译器不一定会警告您)。
flushstdin
函数的定义。fflush
不需要它,因为它是一个已经为您定义的标准C库函数。
两个版本都有问题
正如已经广泛记录的那样,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 filen");
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;
...
}