scanf() 怎樣讀取輸入?
scanf() 開始讀取輸入以後,會在遇到的第乙個空白字元空格(blank)、製表符(tab)或者換行符(newline)處停止讀取。
假定使用了乙個%d說明符來讀取乙個整數。scanf() 函式開始每次讀取乙個輸入字元,它跳過空白字元(空格、製表符和換行符)直到遇到乙個非空白字元。因為它試圖讀取乙個整數,所以scanf() 期望發現乙個數字字元或者乙個符號(+或者-)。如果它發現了乙個數字或乙個符號,那麼它就儲存之並讀取下乙個字元;如果接下來的字元是乙個數字,它儲存這個數字,並讀取下乙個字元。就這樣,scanf() 持續讀取和儲存字元直到它遇到乙個非數字的字元。如果遇到了乙個非數字的字元,它就得出結論:已經到了整數的尾部。scanf()把這個非數字字元放回輸入。這就意味著當程式下一次開始讀取輸入時,它將從前面被放棄的那個非數字字元開始。最後,scanf() 計算它讀取到的數字的相應數值,並將該值放到指定的變數中。
如果使用了字段寬度,那麼scanf() 在字段結尾或者在第乙個空白字元處(而這中最先到達的乙個)終止。
如果第乙個非空白字元不是數字,將會發生什麼呢?比如說,是a而非乙個數字?這時scanf() 會停在那裡,並把a(或者不管是什麼)放回輸入。沒有把任何值賦給指定的變數,程式下一次讀取輸入時,它就在a處重新開始。如果程式中只有%d說明符,scanf() 永遠也不會越過那個a(去讀下乙個)。而且,如果使用帶有多個說明符的scanf()語句,ansi c要求函式在第乙個出錯的地方停止讀取輸入。
使用其他數字說明符讀取輸入與使用%d的情況相同。主要的區別在於scanf()也許會把更多的字元看作數字的一部分。例如,%x說明符要求scanf()識別十六進製制數字a到f和a到f。浮點說明符要求scanf() 識別小數點、指數記數法(e-notation)、新的p記數法(p-notation)。
如果使用%s說明符,那麼空白字元以外的所有字元都是可以接受的,所以scanf() 跳過空白字元直到遇到第乙個非空白字元,然後儲存再次遇到空白字元之前的所有非空白字元。這就意味著%s使scanf() 讀取乙個單詞,也就是說,乙個不包含空白字元的字串。如果使用字段寬度,scanf() 在字段的結尾或者第乙個空白字元處停止。不能通過字段寬度使得scanf() 用乙個%s說明符讀取多於乙個字的輸入。最後一點:當scanf() 把字串放在乙個指定的陣列中時,它新增終止的』\0』使得陣列內容成為乙個c字串。
如果使用%c說明符,那麼所有的輸入字元都是平等的。如果下乙個輸入字元是乙個空格或者換行符,將會把這個空格或換行符賦給指定的變數;不會跳過空白字元。
scanf() 函式允許把普通字元放在格式字串中。除了空格字元之外的普通字元一定要與輸入字串準確匹配。格式字串中的空格意味著跳過下乙個輸入項之前的任何空格。(「任何空格」的概念包括沒有空格的特殊情況)
除了%c以外的說明符會自動跳過輸入項之前的空格,所以scanf(「%d%d」, &n, &m) 與scanf(「%d %d」, &n, &m) 的行為是相同的。對於%c來說,向格式字串中新增乙個空格將導致一些區別。例如:如果在格式字元傳中%c之前有乙個空格,那麼scanf() 會調到第乙個非空白字元處。也就是說,命令scanf(「%c」, &ch) 讀取在輸入中遇到的第乙個字元,而scanf(「 %c」, &ch) 則讀取遇到的第乙個非空白字元。
scanf() 函式返回成功讀入的項的個數 。如果沒有讀取任何專案(當它期望乙個數字卻鍵入了乙個非數字字串時就會發生這種情況),scanf() 會返回值0。當它檢測到「檔案結尾」(end of file)時,它返回eof(eof – end of file,eof是在檔案stdio.h中定義的特殊值,一般,#define 指令把eof的值定義為-1)。
總結:
空白字元(製表符、空格和換行符)對於scanf() 如何處理輸入起著至關重要的作用。除了在%c模式(它讀取下乙個字元)下外,在讀取輸入時,scanf() 會跳過空白字元直到第乙個非空白字元處。然後它會一直讀取字元,直到遇到空白字元,或遇到乙個不符合正在讀取的型別的字元。考慮如果讓幾個不同的scanf() 輸入模式讀取相同的輸入行,將會產生什麼情況。假如有如下輸入行:
-13.45e12# 0
注意,#和0之間有乙個空格。
首先,假定使用%d模式,scanf() 會讀取三個字元(-13)並在小數點處停止,將小數點作為下乙個輸入字元。然後,scanf() 將會把字串行-13轉換成相應的整數數值,並將該值儲存在目標整型變數中。
接著,假定scanf() 以%f模式讀取相同的行,它將會讀取字元-13.45e12,並在#符號處停止,將它作為下乙個輸入字元。然後它把字串行-13.45e12轉換成相應的浮點數值,並將改制儲存在目標浮點變數中。
假定scanf() 以%s模式讀取相同的行,它將會讀取-13.45e12#,並在空格處停止,將這個空格作為下乙個輸入字元。然後他將把這10個字元的字元**儲存到目標字元陣列中,並在結尾附加乙個空字元。
最後假定scanf() 使用%c說明符讀取相同的行,它將會讀取並儲存第乙個字元,在這裡是乙個空格。
scanf函式的輸入
是不是也有人和我一樣,有時候輸入達不到自己預想結果呢?又很難找到自己的錯誤,覺得輸入的格式是對的,但是儲存卻不再在自己預想的位置。下面來講一下我關於字元和數字輸入的順序和方式的認識。首先我們來看第乙個 include includevoid main 是不是感覺是乙個非常簡單的程式。但有時候不懂也是...
scanf 函式問題
今晚研究一下scanf函式 大部分內容 於c語言中文網中 c語言常見問題集 我只不過是做了綜合 1 首先,傳給scanf的必須是指標,對於每個值,scanf都會寫入指標所值的位置,所以必須加 在寫程式時候經常會忘記。2 scanf 函式的返回值反映的是按照指定的格式符正確讀入的資料的個數。如果輸入資...
scanf 函式的引數輸入型別不匹配問題
scanf 函式的引數輸入型別不匹配問題 這是我在csdn論壇上見到的問題,這個錯誤有時候會讓人莫名其妙。include main 當輸入a 回車 後,會直接跳過下面 個scanf語句,直接輸出為 123 t 原因 對於scanf d c a,c scanf語句執行時,首先試圖從緩衝區中讀入乙個 d...