天天看點

清空輸入流

函數名:   scanf  

功     能:   執行格式化輸入  

用     法:   int   scanf(char   *format[,argument,...]);

scanf()函數是通用終端格式化輸入函數,它從标準輸入裝置(鍵盤)   讀取輸入的資訊。可以讀入任何固有類型的資料并自動把數值變換成适當的機内格式。

其調用格式為:             scanf( " <格式化字元串> ", <位址表> );

scanf()函數傳回成功指派的資料項數,出錯時則傳回EOF。

其控制串由三類字元構成:

1。格式化說明符;

2。空白符;

3。非空白符;

(A)                                 格式化說明符

格式字元                       說明

%a                                   讀入一個浮點值(僅C99有效)  

%A                                   同上

%c                                   讀入一個字元

%d                                   讀入十進制整數

%i                                   讀入十進制,八進制,十六進制整數

%o                                   讀入八進制整數

%x                                   讀入十六進制整數

%X                                   同上

%c                                   讀入一個字元

%s                                   讀入一個字元串

%f                                   讀入一個浮點數

%F                                   同上

%e                                   同上

%E                                   同上

%g                                   同上

%G                                   同上

%p                                   讀入一個指針

%u                                   讀入一個無符号十進制整數

%n                                   至此已讀入值的等價字元數

%[]                                 掃描字元集合

%%                                   讀%符号

附加格式說明字元表

修飾符                                               說明

L/l   長度修飾符                               輸入 "長 "資料

h   長度修飾符                                   輸入 "短 "資料

W   整型常數                                       指定輸入資料所占寬度

*   星号                                               空讀一個資料  

hh,ll同上h,l但僅對C99有效。

(B)                   空白字元  

空白字元會使scanf()函數在讀操作中略去輸入中的一個或多個空白字元,空白符可以是space,tab,newline等等,直到第一個非空白符出現為止。

(C)                 非空白字元  

一個非空白字元會使scanf()函數在讀入時剔除掉與這個非空白字元相同的字元。  

注:scanf()控制串知識就介紹到這裡(應該比較齊全了^_^),如有遺漏下次補上。下面将結合實際例程,一一闡述.

三、             scanf()函數的控制串的使用

例1.

#include   "stdio.h "  

int   main(void)  

{  

    int   a,b,c;  

    scanf( "%d%d%d ",&a,&b,&c);    

    printf( "%d,%d,%d\n ",a,b,c);    

    return   0;

}      

運作時按如下方式輸入三個值:

3□4□5 ↙(輸入a,b,c的值)

3,4,5   (printf輸出的a,b,c的值)

      (1)   &a、&b、&c中的&是位址運算符,分别獲得這三個變量的記憶體位址。

      (2)   "%d%d%d "是按十進值格式輸入三個數值。輸入時,在兩個資料之間可以用一個或多個空格、tab鍵、Enter鍵分隔。

            以下是合法輸入方式:  

            ①   3□□4□□□□5↙

            ②   3↙

                  4□5↙

            ③   3(tab鍵)4↙

                  5↙

例2.

#include   "stdio.h "  

int   main(void)  

{  

    int   a,b,c;  

    scanf( "%d,%d,%d ",&a,&b,&c);

    printf( "%d,%d,%d\n ",a,b,c);    

    return   0;

}      

運作時按如下方式輸入三個值:

3,4,5 ↙(輸入a,b,c的值)

或者

3,□4,□5 ↙(輸入a,b,c的值)

3,□□□4,□5 ↙(輸入a,b,c的值)

......

都是合法的,但是 ", "一定要跟在數字後面,如:

3□,4,□5 ↙就非法了,程式出錯。(解決方法與原因後面講)

再如:

1、sacnf()中的變量必須使用位址。

                 int   a,   b;

scanf( "%d%d ",a,b);   //錯誤

scanf( "%d%d ",&a,&b);  

2、scanf()的格式控制串可以使用其它非空白字元,但在輸入時必須輸入這些字元。

例:

scanf( "%d,%d ",&a,&b);  

輸入:   3,4   ↙(逗号與 "%d,%d "中的逗号對應)  

scanf( "a=%d,b=%d ",&a,&b);  

輸入:   a=3,b=4   ↙( "a= ", "b= ",逗号與 "%d,%d "中的 "a= ", "b= "及逗号對應)

3、在用 "%c "輸入時,空格和“轉義字元”均作為有效字元。

例:

scanf( "%c%c%c ",&c1,&c2,&c3);  

輸入:a□b□c↙  

結果:a→c1,□→c2,b→c3   (其餘被丢棄)  

scanf()函數接收輸入資料時,遇以下情況結束一個資料的輸入:(不是結束該scanf函數,scanf函數僅在每一個資料域均有資料,并按回車後結束)。

                ①   遇空格、“回車”、“跳格”鍵。

                ②   遇寬度結束。

                ③   遇非法輸入。

問題二:scanf()函數不能正确接受有空格的字元串?如:   I   love   you!

#include   <stdio.h>

int   main()

{

        char   str[80];

        scanf( "%s ",str);

        printf( "%s ",str);

        return   0;

}

輸入:I   live   you!

輸出:I

              scanf()函數接收輸入資料時,遇以下情況結束一個資料的輸入:(不是結束該scanf函數,scanf函數僅在每一個資料域均有資料,并按回車後結束)。

                ①   遇空格、“回車”、“跳格”鍵。

                ②   遇寬度結束。

                ③   遇非法輸入。

是以,上述程式并不能達到預期目的,scanf()掃描到 "I "後面的空格就認為對str的指派結束,并忽略後面的 "love   you! ".這裡要注意是 "love   you! "還在鍵盤緩沖區(關于這個問題,網上我所見的說法都是如此,但是,我經過調試發現,其實這時緩沖區字元串首尾指針已經相等了,也就是說緩沖區清空了,scanf()函數應該隻是掃描stdin流,這個殘存資訊是在stdin中)。我們改動一下上面的程式來驗證一下:

#include   <stdio.h>

int   main()

{

        char   str[80];

        char   str1[80];

        char   str2[80];

        scanf( "%s ",str);

        printf( "%s ",str);

        sleep(5);

        scanf( "%s ",str1);

        scanf( "%s ",str2);

        printf( "\n%s ",str1);

        printf( "\n%s ",str2);

        return   0;

}

輸入:I   love   you!

輸出:I

            love

            you!

好了,原因知道了,那麼scanf()函數能不能完成這個任務?回答是:能!别忘了scanf()函數還有一個   %[]   格式控制符(如果對%[]不了解的請檢視本文的上篇),請看下面的程式:

#include   "stdio.h "

int   main()

{

        char   string[50];

          scanf( "%[^\n] ",string);

          printf( "%s\n ",string);

          return   0;

}

問題三:鍵盤緩沖區殘餘資訊問題

#include   <stdio.h>

int   main()

{

        int   a;

        char   c;

        do

        {

                scanf( "%d ",&a);

                scanf( "%c ",&c);

                printf( "a=%d           c=%c\n ",a,c);

        }while(c!= 'N ');

}

      scanf( "%c ",&c);這句不能正常接收字元,什麼原因呢?我們用printf( "c=%d\n ",c);将C用int表示出來,啟用printf( "c=%d\n ",c);這一句,看看scanf()函數賦給C到底是什麼,結果是   c=10   ,ASCII值為10是什麼?換行即\n.對了,我們每擊打一下 "Enter "鍵,向鍵盤緩沖區發去一個“回車”(\r),一個“換行 "(\n),在這裡\r被scanf()函數處理掉了(姑且這麼認為吧^_^),而\n被scanf()函數“錯誤”地賦給了c.

解決辦法:可以在兩個scanf()函數之後加個fflush(stdin);,還有加getch();   getchar();也可以,但是要視具體scanf()語句加那個,這裡就不分析了,讀者自己去摸索吧。但是加fflush(stdin);不管什麼情況都可行。

函數名:   fflush  

功     能:   清除一個流  

用     法:   int   fflush(FILE   *stream);  

#include   <stdio.h>

int   main()

{

        int   a;

        char   c;

        do

        {

                scanf( "%d ",&a);

                fflush(stdin);

                scanf( "%c ",&c);

                fflush(stdin);

                printf( "a=%d           c=%c\n ",a,c);

        }while(c!= 'N ');

}            

這裡再給一個用“空格符”來處理緩沖區殘餘資訊的示例:

運作出錯的程式:

#include   <stdio.h>

int   main()

{

        int   i;

        char   j;

        for(i   =   0;i   <   10;i++)

        {

                scanf( "%c ",&j);

        }

}

使用了空格控制符後:

#include   <stdio.h>

int   main()

{

        int   i;

        char   j;

        for(i   =   0;i   <   10;i++)

        {

                scanf( "   %c ",&j);

        }

}

        可以運作看看兩個程式有什麼不同。

問題四       如何處理scanf()函數誤輸入造成程式死鎖或出錯?

#include   <stdio.h>

int   main()

{

    int   a,b,c;    

    scanf( "%d,%d ",&a,&b);

    c=a+b;

    printf( "%d+%d=%d ",a,b,c);

}

如上程式,如果正确輸入a,b的值,那麼沒什麼問題,但是,你不能保證使用者每一次都能正确輸入,一旦輸入了錯誤的類型,你的程式不是死鎖,就是得到一個錯誤的結果,呵呵,這可能所有人都遇到過的問題吧?

解決方法:scanf()函數執行成功時的傳回值是成功讀取的變量數,也就是說,你這個scanf()函數有幾個變量,如果scanf()函數全部正常讀取,它就傳回幾。但這裡還要注意另一個問題,如果輸入了非法資料,鍵盤緩沖區就可能還個有殘餘資訊問題。

正确的例程:

#include   <stdio.h>

int   main()

{

    int   a,b,c;    

    while(scanf( "%d,%d ",&a,&b)!=2)fflush(stdin);

    c=a+b;

    printf( "%d+%d=%d ",a,b,c);

}