最近在網上看到幾篇關於scanf函數的文章,與大家分享一下!
scanf()函數探討(1)——使用說明<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
(1)例如: %s 表示讀串而 %d 表示讀整數。格式串的處理順序爲從左到右,格式說明符逐一與變元表中的變元匹配。爲了讀取長整數,可以將 l(ell) 放在格式說明符的前面;爲了讀取短整數,可以將 h 放在格式說明符的前面。這些修飾符可以與 d、i、o、u 和 x 格式代碼一起使用。 (2)默認情況下,a、f、e 和 g 告訴 scanf() 爲 float 分配數據。 如果將 l(ell) 放在這些修飾符的前面,則 scanf() 爲 double 分配數據。使用 L 就是告訴 scanf(),接收數據的變量是 long double 型變量。 (3)控制串中的空白符使 scanf() 在輸入流中跳過一個或多個空白行。空白符可以是空格(space)、製表符(tab)和新行符(newline)。本質上,控制串中的空白符使 scanf() 在輸入流中讀,但不保存結果,直到發現非空白字符爲止。 (4)非空白符使 scanf() 在流中讀一個匹配的字符並忽略之。例如,"%d,%d" 使 scanf() 先讀入一個整數,讀入中放棄逗號,然後讀另一個整數。如未發現匹配,scanf() 返回。 (5)scanf() 中用於保存讀入值的變元必須都是變量指針,即相應變量的地址。 (6)在輸入流中,數據項必須由空格、製表符和新行符分割。逗號和分號等不是分隔符,比如以下代碼:scanf( "%d %d", &r, &c );將接受輸入 10 20,但遇到 10,20 則失敗。 (7)百分號(%)與格式符之間的星號(*)表示讀指定類型的數據但不保存。因此, (8)格式命令可以說明最大域寬。 在百分號(%)與格式碼之間的整數用於限制從對應域讀入的最大字符數。例如,希望向 address 讀入不多於 20 個字符時,可以書寫成如下形式: (10)雖然空格、製表符和新行符都用做域分割符號,但讀單字符操作中卻按一般字符處理。例如,對輸入流 "x y" 調用: (12)注意,控制串中的其它字符,包括空格、製表符和新行符,都用於從輸入流中匹配並放棄字符,被匹配的字符都放棄。例如,給定輸入流 "10t20",調用: (13)ANSI C 標準向 scanf() 增加了一種新特性,稱爲掃描集(scanset)。 掃描集定義一個字符集合,可由 scanf() 讀入其中允許的字符並賦給對應字符數組。掃描集合由一對方括號中的一串字符定義,左方括號前必須綴以百分號。 例如,以下的掃描集使 scanf() 讀入字符 A、B 和 C:%[ABC] 使用掃描集時,scanf() 連續喫進集合中的字符並放入對應的字符數組,直到發現不在集合中的字符爲止(即掃描集僅讀匹配的字符)。返回時,數組中放置以 null 結尾、由讀入字符組成的字符串。用字符 ^ 可以說明補集。把 ^ 字符放爲掃描集的第一字符時,構成其它字符組成的命令的補集合,指示 scanf() 只接受未說明的其它字符。對於許多實現來說,用連字符可以說明一個範圍。例如,以下掃描集使 scanf() 接受字母 A 到 Z: %[A-Z] 重要的是要注意掃描集是區分大小寫的。因此,希望掃描大、小寫字符時,應該分別說明大、小寫字母。
|
scanf()函數探討(2)——使用說明
(15)對於字符串數組或字符串指針變量,由於數組名和指針變量名本身就是地址,因此使用scanf()函數時,不需要在它們前面加上"&"操作符。 例如:
(16)可以在格式化字符串中的"%"各格式化規定符之間加入一個整數,表示任何讀操作中的最大位數。如上例中若規定只能輸入10字符給字符串指針p,則第一條scanf() 函數語句變爲:scanf("%10s", p); 程序運行時一旦輸入字符個數大於10,p就不再繼續讀入,而後面的一個讀入函數即scanf("%s", str)就會從第11個字符開始讀入。 (17) scanf()函數中沒有精度控制。 如: scanf("%5.2f",&a); 是非法的。不能企圖用此語句輸入小數爲2位的實數。 (18)scanf中要求給出變量地址,如給出變量名則會出錯 如 scanf("%d",a);是非法的,應改爲scnaf("%d",&a);纔是合法的。 (19)在輸入多個數值數據時,若格式控制串中沒有非格式字符作輸入數據之間的間隔則可用空格,TAB或回車作間隔。C編譯在碰到空格,TAB,回車或非法數據(如對“%d”輸入“12A”時,A即爲非法數據)時即認爲該數據結束。 (20)在輸入字符數據(%c)時,若格式控制串中無非格式字符,則認爲所有輸入的字符均爲有效字符。 例如:scanf("%c%c%c",&a,&b,&c); 輸入爲: d e f 則把'd'賦予a, ' (空格)'賦予b,'e'賦予c。因爲%c 只要求讀入一個字符,後面不需要用空格作爲兩個字符的間隔,因此把' '作爲下一個字符送給b。只有當輸入爲:def 時,才能把'd'賦於a,'e'賦予b,'f'賦予c。 如果在格式控制中加入空格作爲間隔, 如 scanf ("%c %c %c",&a,&b,&c);則輸入時各數據之間可加空格。 我們用一些例子來說明一些規則:
由於scanf函數"%c%c"中沒有空格,輸入M N,結果輸出只有M。而輸入改爲MN時則可輸出MN兩字符,見下面的輸入運行情況: input character a,b MN (你輸入的值) MN (屏幕上顯示的值)
本例表示scanf格式控制串"%c %c"之間有空格時, 輸入的數據之間可以有空格間隔。 (21)如果格式控制串中有非格式字符則輸入時也要輸入該非格式字符。 例如: scanf("%d,%d,%d",&a,&b,&c); 其中用非格式符“ , ”作間隔符,故輸入時應爲: 5,6,7 (與scanf 雙引號之間的格式必須一樣) 又如: scanf("a=%d,b=%d,c=%d",&a,&b,&c); 則輸入應爲 a=5,b=6,c=7 如輸入的數據與輸出的類型不一致時,雖然編譯能夠通過,但結果將不正確。
由於輸入數據類型爲整型,而輸出語句的格式串中說明爲長整型,因此輸出結果和輸入數據不符。輸出並不是輸入的值。如將Scanf("%d",&a); 語句改爲 scanf("%ld",&a); 輸入數據爲長整型,輸入輸出數據才相等。 |
scanf()函數探討(3)——常見錯誤和解答
1.空白符問題
結果要輸入兩個數程序才結束,而不是預期的一個。 2.緩衝區問題
或者不用scanf,而用gets()函數,如:
但要注意:這個函數自動把你最後敲的回車轉換爲字符'/0'。如果你的輸入超過了數組的大小,那麼就會產生錯誤。
當輸入a 回車 後,會直接跳過下面2個scanf語句,直接輸出爲
輸入:2 回車a 回車
補充:scanf中一種很少見但很有用的轉換字符:[...]和[ ^...]。
運行,輸入:1234werew後,結果是:1234。通過運行可以發現它的作用是:如果輸入的字符屬於方括號內字符串中某個字符,那麼就提取該字符;如果一經發現不屬於就結束提取。該方法會自動加上一個字符串結束符到已經提取的字符後面。 4.一些問題
如果將第8行改爲 scanf("i=%d j=%d",&i,&j); 則程序運行結果變成 please input num:i=1 j=2 num=6 Programm is complete. (原本希望能重複第一行再讓我輸入) 爲什麼第二次不能輸入? 解答:象scanf("i=%d j=%d",&i,&j);這樣的輸入方式比較特別,顯然在第一次輸入後沒有象正常情況一樣清楚輸入緩衝區,這樣第二次執行scanf時,程序並沒有讓你輸入而是直接讀入上次輸入的結果。如果你一定要 這麼做,應該在scanf之前加上: fflush(stdin); 這樣清楚掉鍵盤緩衝區。
爲什麼要把scanf("%c",varname)一定改成scanf(" %c")纔可以正確接收字符? 答覆: 類似上題,在%c的前面必須有一個空格,否則系統會將你前面輸入別的值之後鍵入的回車符讀入該變量,造成死循環。當然,如果scanf("%c",&varname)是第一條讀入語句,就可以不需要空格。
在用“%c”格式輸入字符時,“空格字符”和“轉義字符”都作爲有效字符輸入。 scanf("%c%c%c",&c1,&c2,&c3); 如輸入a b c 字符“a”送給c1,字符“ ”送給c2,字符“b”送給c3,因爲%c只要求讀入一個字符,後面不需要用空格作爲兩個字符的間隔。
例如,a已定義爲整型,b定義爲實型 a=3;b=4.5; printf("%f%d/n",a,b); 編譯時不給出出錯信息,但運行結果將與原意不符。這種錯誤尤其需要注意。
scanf("%7.2f",&a); 這樣做是不合法的,輸入數據時不能規定精度。
scanf("%s",&str); C語言編譯系統對數組名的處理是:數組名代表該數組的起始地址,且scanf函數中的輸入項是字符數組名,不必要再加地址符&。應改爲:scanf("%s",str); |