C语言 fflush(stdin)和flushstdin()的区别



使用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库的一些版本实现了fpurgefabort调用,它们做同样的事情,但这些也不是标准的。)还要注意,刷新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标准定义的,所以使用它会使您的程序不可移植(并且您的编译器不一定会警告您)。

顺便提一下,"那个void的东西"是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;
    ...
}

最新更新