c語言scanf陷阱 緩衝區引起的跳過輸入問題

2021-08-28 23:38:27 字數 2576 閱讀 7556

小白在學習c語言的時經常會有不懂的地方,有時候因為乙個小小的問題,或者因為乙個小小的概念沒有理解清楚,都會造成懵逼、無解的情況,然而這樣的情況在程式設計中經常出現,所以不不僅在c語言中,還存在大多數的程式語言中:本文要說的就是關於c緩衝區特性引發scanf()方法的一些奇怪現象:

1.本文描述的編譯環境均在虛擬機器linux-centos7系統下執行

2.本文從編譯到執行均使用 linux root 賬戶操作

3.本文編譯軟體使用的是 linux gcc 編譯器

5.解決問題的關鍵方法 : getchar()

1.在控制台獲取的輸入時,任何輸入都將視為字元,包括 '回車(enter)' 鍵也是乙個字元

2.使用scanf()方法,在輸入格式使用%c時,只會獲取第乙個字元,如果第乙個字元時空白,則跳過空白獲取下乙個字元,以此往復

3.按照scanf()方法獲取字串的規則,如果scanf獲取完後就會停止擷取字元,並將剩下的字元儲存在快取區,作為下次scanf()方法從控制台獲取字串的輸入

通常在開始學編譯c語言的時候,初學者都要在控制台使用scanf()方法與使用者互動,而且使用了多個scanf()方法與使用者進行互動,發現有需要使用者第二次輸入單個字元或字串的時候會出現問題。

比如:上個scanf()方法要求從控制台獲取乙個字元輸入或字串輸入,此時按照scanf()方法的規則,在開頭遇到空白(空格)則自動跳過去獲取下乙個字元或字串,在獲取字元或字串完成後,如果後面有空白(空格)則結束獲取字元或字串,此時的問題是:空白(空格)後面還有字元怎麼辦?還有空白(空格)本身也是乙個字元,'回車(enter)'鍵也是乙個字元。

此時,被使用過後的臺輸入字元,將剩下的字元或字串(包括空格和『回車(enter)』在內的字元)儲存在緩衝區,作為下次scanf()方法從控制台獲取字元或字串的輸入

#include //**手動寫的,可能會出錯,謹慎複製!

int main(void)

比如我編譯剛剛寫好的**

#gcc -o two two.c 

沒有報錯,然後我們執行當前目錄下編譯好的two檔案

#./two

然後要求輸入第乙個字串,我們輸入er,按下'回車(enter)':

這時候問題出現了

我們原先設定好的第二次輸入呢?????還留自動留下了乙個空行!!??

其實在我們第一次輸入並按下回車的時候,控制台一共獲得了三個字元,分別是:e、r、回車(enter)。但是因為scanf()方法遇到非字元的時候會結束從控制台的獲取,所以在輸入'er'後,按下 '回車(enter)' 的同時,將'er'這個值以字串的形式賦值給了型別為 'char' 的 'm' 陣列,將使用過後的字串: '回車(enter)' 儲存在控制台輸入的緩衝區,然後繼續執行下一段輸出**,然後又要求使用者輸入。此時,因為上一次被使用過後的字串被儲存在緩衝區,現在scanf()方法從控制台的緩衝區獲取上一次被使用過後的字串,並只擷取第乙個字元: '回車(enter)' ,此時控制台緩衝區才算使用完了。。。。。。驚訝不?

所以在看似被跳過的輸入,其實已經scanf()方法已經獲取了我們的輸入了,這個輸入就是乙個 '回車(enter)' ,只是跟我們理解的輸入不一樣罷了。

我們要做的就是kill掉那個被使用剩下後儲存在控制台輸入緩衝區的字串,使用getchar()方法(getchar()方法是解決目前問題的最簡單的方法,至於getchar()方法特性,請自行查詢),將在控制台輸入緩衝區的使用剩下的字元銷毀掉:其實就是從控制台獲取字元,然後不使用從控制台輸入緩衝區獲取到的字元就算銷毀了。當然,還可以使用清除快取的方法,但是不適用於linux系統

#include //**手動寫的,可能會出錯,謹慎複製!

int main(void)

現在看來已經解決了跳過輸入的問題了:

但是使用一次getchar方法只能kill掉乙個字元,如果我們子在輸入 'er' 的時候,後面再加乙個'空格(\0)'的話,我們的**就不好使了:

還是出現了自動跳過輸入,

由此得出,最後還是不要加空格的好!至於要是考慮出現最後加空格的情況,還是自行解決吧!

C語言scanf 與緩衝區

scanf函式返回值 正整數,表示正確輸入引數的個數。例如執行 scanf d d a,b 如果使用者輸入 3 4 可以正確輸入,返回2 正確輸入了兩個變數 如果使用者輸入 3,4 可以正確輸入a,無法輸入b,返回1 正確輸入了乙個變數 0,表示使用者的輸入不匹配,無法正確輸入任何值。如上例,使用者...

關於scanf 緩衝區

c語言中的輸入函式 包括scanf,getchar等 在接收鍵盤輸入時,把輸入放在了 輸入緩衝區 當scanf getchar 做輸入操作時,以回車符作為結束標誌,並把回車符 n 包含在輸入字串中儲存在緩衝區,再從輸入緩衝區中取走輸入字串賦值給變數,但卻沒有取走回車符 n 再當我們二次呼叫scanf...

scanf 函式緩衝區

1當使用scanf函式接受使用者資料時,輸入的資料不會直接賦值給變數,而是首先將輸入的資料存入緩衝區,輸入的全部資料都會儲存在緩衝區中包括 空格 tab 回車 2當執行scanf函式時會先檢查緩衝區中是否有資料,如果有則直接從緩衝區取出資料賦值給變數,不會讓使用者輸入資料,如果沒有才會讓使用者從控制...