2011-04-12 146 views
5

我想知道標準C庫函數scanf()在我們調用scanf(「%d」,& var)時,如果輸入是整數或字符,當一個字符本身只是一個數字時,該如何檢查? 我知道當它遇到一個非整數時,它將它放回到輸入緩衝區並返回一個-1,但它怎麼知道輸入不是一個整數?scanf()如何檢查輸入是整數還是字符?

回答

3

你說得對,因爲每個字符都被表示爲一個8位整數。解決辦法很簡單:查看該號碼,看它是否在48-57範圍內,這是字符'0' - '9'的SCII代碼範圍。

scanf()source code的行1315開始,我們可以看到這一行動。 scanf()實際上更復雜 - 它也會查看多字節字符來確定數值。 1740行是魔法發生的地方,而角色實際上被轉換爲數字。最後,可能這是最有用的,strtol()函數執行循環來執行該轉換。

+0

感謝您對源代碼的解釋和參考! – vjain27 2011-04-12 03:09:28

3

輸入始終是一個字符串。如果scanf正期待一個整數(因爲您通過它"%d"),它會嘗試將字符串轉換爲一個整數。

+0

但是無論我們投入這將是全數字的ASCII值的序列。不是嗎? – vjain27 2011-04-12 01:42:55

+0

代表數字的ASCII值,你的意思。 scanf採用字符'9',決定它代表一個數字,並將其轉換爲整數9. – Marvo 2011-04-12 01:44:41

+0

是的,這就是它應該做的。鍵盤只會發送ascii字符。 – vjain27 2011-04-12 01:50:51

0

它試圖從流的開頭解析一個有效的十進制整數,實際上是可選的+或 - 然後是一個或多個數字的序列。

+0

你能解釋一下它是如何解析的?例如。它將如何區分A和65的值,因爲A將以65的形式傳遞 - 它的ASCII值? – vjain27 2011-04-12 01:47:58

+0

Uh scant嘗試在此處讀取十進制整數的ASCII表示。字母A不是這樣的一部分。 – 2011-04-12 01:54:22

0

它基本上使用像一個循環:

while (isdigit((ch=getchar())) 
    // ... 
+0

我明白了。謝謝! – vjain27 2011-04-12 03:08:56

0

你誤會了%d格式說明。它不是而是返回輸入字符的ASCII值(可以使用%c表示);它返回字符表示的整數。因此,在'9'的輸入字符上,%d返回值9--而不是'9'的ASCII值。

(好吧,其實%d着眼於字符序列,因此,如果輸入的是隨後'0'其次' ''9',它會解釋,由於90)。

1

基本上,scanf函數根據您傳遞的轉換說明符匹配正則表達式。如果您指定%d,則告知scanf將輸入與'0''9'(可選帶有前導+-字符)之間的一個或多個字符的正則表達式匹配。然後它將該字符序列轉換爲等效的整數值。

一個非常簡單的版本可能是這個樣子:

while (isdigit(c = fgetc(stream)) 
    val = val * 10 + valueOf(c); 
ungetc(c, stream); 

其中isdigit是一個標準庫函數返回true(非零)如果字符值表示十進制數字,和valueOf是一個用戶定義的函數將表示整數('0'-'9')的字符映射爲等效整數值(0-9)(我不知道標準庫函數會爲單個字符值執行此操作)。爲什麼不從c減去'0'以獲得等效的整數值?根據編碼的不同,不能保證所有的十進制整數字符都會按順序排列(All The World is Not ASCII);最好將實際轉換委託給知道當前編碼的函數。

2

在你提的這是默認控股整數只有那麼%d scanf函數聲明,它理解該變量作爲整數

相關問題