2011年11月1日 星期二

C - fflush() & fpurge()

在寫C程式的時候,我們經常會碰到 scanf() 的一些陷阱,很多時候我們必須用函式來清除標準輸入的緩衝區,例如以下的程式碼:

#include<stdio.h>
#include<stdlib.h>

int main()
{
    int size = 0;
    int i=0,j=0;
    
    do
    {
       printf("Please input rows of triangle, exit please input -1\n");
       scanf("%d",&size);
    
        if(size<0)
        { return 0; }
        else if(size==1 || size ==0) 
        {    printf("Can not form a triangle!\n");        }
        else if(size >100)
        {
            printf("Too large!!!\n");        
        }
        else
        {
            for(i=0;i<size;i++)
            {
                for(j=0;j<size-(i+1);j++)
                {    printf(" ");    }
            
                for(j=0;j<2*(i+1)-1;j++)
                {    printf("*");    }
                
                printf("\n"); 
            }
        }
        
     fpurge(stdin); /**/
     size = 0;
    }while(size>=0);

    return 0;
}



這是個簡單的印出三角型的程式碼,會有以下的結果:
C:\>Please input rows of triangle, exit please input '-1'
2
  *
***
Please input rows of triangle, exit please input '-1'
3
    *
  ***
*****
Please input rows of triangle, exit please input '-1'
-1
C:\>

注意到在while前面兩行,會有一個 fpurge() 嗎? 我想大多數的人google一下應該會發現中文的資料並不多,而且會發現他與我們熟知的 fflush() 功能很類似,沒錯!這個函式與 fflush() 具有一樣的功能,都是清除緩衝區內的資料,那究竟這兩個的差別在哪裡呢?

首先,大家可以在 Windows 上面編譯看看這支程式,會發現 fpurge()竟然是 undefine 的函式,是的,因為這個程式碼是我在學校的程式設計課上面所做的,而當時採用的平台是 FreeBSD,因此在這個 fpurge() 是在 FreeBSD 等Linux中定義的函式,在Windows 平台上似乎沒有這個函式
但是當大家到 Linux 中去測試這支程式之後,可以再把 fpurge() 改回 fflush(),會發現 fflush()在 Linux 中竟然沒有作用,但是他仍然有被定義喔!  (所已在等待誰可以告訴我這兩個東西的實質差異)


1 則留言:

  1. Linux:
    The fflush() function causes any buffered output data for stream to be written to file
    The fpurge() function clears all buffered input and output data on stream
    所以fflush是強制輸出資料嗎?

    另外有在別的論壇找到:
    Never do fflush(stdin);. In GNU/Linux it doesn't work, but in other systems it can lead to undefined behaivor.
    fpurge is a BSD extension, according to its man page... if you use it, your code gets non-standard. fflush is standard.

    回覆刪除