詳解scanf函式

2021-05-23 03:24:00 字數 4077 閱讀 9769

函式名: scanf

功能: 執行格式化輸入

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

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

其呼叫格式為:scanf("《格式化字串》",《位址表》);

scanf()函式返回成功賦值的資料項數,出錯時則返回eof。

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

1。格式化說明符;

2。空白符;

3。非空白符;

格式化字串的一般形式為:[賦值抑制標記][字段寬度][精度]型別說明符其中方括號中的項為可選項。

賦值抑制標記*:該字元命令scanf按當前的轉換說明符進行轉換,但忽略轉換後的結果,即不將它賦給任何變數。

字段寬度:用於指定輸入欄位的寬度,如果沒有指定,則以空白作為結束標記。

精度:是乙個字元,可以是h、l、l,用於改變它後面的型別說明符的含義。

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

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

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

h: 用於型別說明符d、i、o、u、x、x、n前,指定引數是指向short int或unsigned short int的指標。

l: 用於型別說明符d、i、o、u、x、x、n前,指定引數是指向long或unsigned long的指標。用於型別說明符a、a、e、e、f、f、g、g前,指定引數是指向double的指標。

l: 用於型別說明符a、a、e、e、f、f、g、g前,指定引數是指向long double的指標。

hh: 用於型別說明符d、i、o、u、x、x、n前,指定引數是指向signed char或unsigned char的指標。

ll: 用於型別說明符d、i、o、u、x、x、n前,指定引數是指向long long或unsigned long long的指標。

轉換說明符

格式字元說明

%a 讀入乙個浮點值(僅c99有效)

%a 同上

%c 讀入乙個字元

%d 讀入十進位制整數

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

%o 讀入八進位制整數

%x 讀入十六進製制整數

%x 同上

%s 讀入乙個字串,並在末尾加上空字元。

%f 讀入乙個浮點數

%f 同上

%e 同上

%e 同上

%g 同上

%g 同上

%p 讀入乙個指標

%u 讀入乙個無符號十進位制整數

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

%[...]掃瞄字元集合,只讀取方括號裡面列出的字元。遇到不匹配的字元、達到指定的寬度或使用者按下回車,立即停止讀取。為讀取]字元,應首先列出它...]。在字串末尾加上空字元。

%[^...]與[...]相同,不過只讀取方括號中沒有列出的字元。

%% 讀%符號,不執行任何賦值操作。

空白字元

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

非空白字元

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

scanf()函式的控制串的使用

例1.

執行時按如下方式輸入三個值:

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

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

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

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

例2.

執行時按如下方式輸入三個值:

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()函式控制串運用出現的常見錯誤及對策技巧

問題一:scanf()函式不能正確接受有空格的字串?如: i love you!

輸入:i live you!

輸出:i

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

① 遇空格、「回車」、「跳格」鍵。

② 遇寬度結束。

③ 遇非法輸入。

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

#i nclude

int main(void)

輸入:i love you!

輸出:

ilove

you!

好了,原因知道了,那麼scanf()函式能不能完成這個任務?回答是:能!別忘了scanf()函式還有乙個 % 格式控制符,請看下面的程式:

問題二:鍵盤緩衝區殘餘資訊問題

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);

函式名: fflush

功能: 清除乙個流

用法: int fflush(file *stream);

這裡再給乙個用「空格符」來處理緩衝區殘餘資訊的示例:

執行出錯的程式:

使用了空格控制符後:

可以執行看看兩個程式有什麼不同。

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

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

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

正確的例程:

C語言格式輸入函式scanf 詳解

scanf函式稱為格式輸入函式,即按使用者指定的格式從鍵盤上把資料輸入到指定的變數之中。scanf函式是乙個標準庫函式,它的函式原型在標頭檔案 stdio.h 中。與printf函式相同,c語言也允許在使用scanf函式之前不必包含stdio.h檔案。scanf函式的一般形式為 scanf 格式控制...

C C語言格式輸入函式scanf 詳解

scanf函式稱為格式輸入函式,即按使用者指定的格式從鍵盤上把資料輸入到指定的變數之中。scanf函式是乙個標準庫函式,它的函式原型在標頭檔案 stdio.h 中。與printf函式相同,c語言也允許在使用scanf函式之前不必包含stdio.h檔案。scanf函式的一般形式為 scanf 格式控制...

C語言天天練(二十) scanf函式詳解

引言 scanf函式雖然是學習c語言時比較早就接觸的乙個函式,但在使用過程中,發現真正掌握它卻並不容易。本文就通過各種例子來詳細的總結一下該函式的各種用法,假設它的呼叫格式為 scanf 格式化字串 位址表 1 一般使用scanf函式時都是為某個變數賦值,不考慮它的返回值。但是任何函式都是需要返回的...