gcc下fflush失效

今天编译一程序涉及到了键盘缓冲区的清除问题,在VC下完全没问题的代码却不能在gcc下运行成功,作此笔记以留念:
VC下代码:
#include<stdio.h>
void main()
{
float a,b;
int tag=0;
char ch;
float result;

    printf("Input two number:"); 
    scanf("%f%f",&a,&b); 
    fflush(stdin); 
    printf("Input arithmetic lable(+-*/):"); 
    scanf("%c",&ch); 


    switch (ch) 
    { 
            case '+':result=a+b;break; 
            case '-':result=a-b;break; 
            case '*':result=a*b;break; 
            case '/':if(!b) 
                     { 
                             printf("divisor is zero!\n"); 
                             tag=1; 
                     } 
                     else 
                             result=a/b; 
                     break; 
            default:printf("illegal arithmetic lable\n"); 
                    tag=1; 
    } 
    if(!tag) 
            printf("%.2f %c %.2f=%.2f\n",a,ch,b,result); 

}

一网友的解释如下:

如何清除stdin缓存中的数据?

一。这问题没有什么很标准的做法:
方法1、fflush(): VC上面使用fflush()可以成功, 而在gcc上面使用fflush()却不能成功。
方法2、setbuf(): 虽然在gcc上面,使用这种方式确实可以清空输入流. 但不建议使用。
方法3、通过 while 循环把输入流中的余留数据“吃”掉:
int c;
while ((c=getchar()) != ‘\n’ && c != EOF);

    /*可直接将这2句代码当成fflush(stdin)的替代,直接运行可清除输入缓存流*/

二。解释:

  1. fflush()不行的原因如下:

C-FAQ中如下:
Question 12.26
How can I flush pending input so that a user’s typeahead isn’t read at the next prompt? Will fflush(stdin) work?


fflush is defined only for output streams. Since its definition of ``flush’’ is to complete the writing of buffered characters (not to discard them), discarding unread input would not be an analogous meaning for fflush on input streams.

There is no standard way to discard unread characters from a stdio input stream, nor would such a way be sufficient unread characters can also accumulate in other, OS-level input buffers.

C标准(ISO/IEC 9899:1999 standard)规定fflush(stdin)操作是未定义的<参看《ISO/IEC 9899:1999 standard》p270>;。也就是说不一定能实现刷新功能,但有的编译器可能不遵循标准,对fflush(stdin)操作不予警告,并且有时可能产生正确的结果,但最好不要这样使用。
VC上面使用fflush()可以成功, 而在gcc上面使用fflush()却不能成功。

以下是 C99 对 fflush 函数的定义:

int fflush(FILE *stream);
如果 stream 指向输出流或者更新流(update stream),
并且这个更新流最近执行的操作不是输入,
那么 fflush 函数将把这个流中任何待写数据传送至宿主环境(host environment)写入文件。

否则,它的行为是未定义的。对于fflush(FILE *out)这种是肯定会成功的,但是对于fflush(stdin),fflush(stdout),不能保证一定能刷新。

原文如下:
int fflush(FILE *stream);
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.

其中,宿主环境可以理解为操作系统或内核等。

由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的,至少是移植性不好的。

  1. setbuf()的方法也是不符合标准的. 虽然在有些场合它通过将输入设置为无缓冲形式, 以此来刷新输入流, 但是不太可靠。
    虽然在gcc上面,使用这种方式确实可以清空输入流. 但不建议使用.

其编译后不能运行成功的主要原因在于gcc下fflush(stdin)没起作用,所以
printf(“Input two number:”);
scanf("%f%f",&a,&b);
fflush(stdin);
printf(“Input arithmetic lable(±/)😊;
scanf("%c",&ch);
可以改为:
printf(“Input two number:”);
scanf("%f%f",&a,&b);
printf("Input arithmetic lable(±
/):”);
scanf(" “);
scanf(”%c",&ch);
这样在gcc下即可编译执行成功,不足之处望指正共同进步。。。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hvk_l

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值