c语言scanf()函数的原理
scanf()函數的原理
想象輸入設備(鍵盤)連接著一個叫“緩沖”的東西,把緩沖認為是一個字符數組。
當你的程序執行到scanf時,會從你的緩沖區讀東西,如果緩沖區是空的,就阻塞住,等待你從鍵盤輸入。
現在假設你的緩沖區里有:abcd\n1234\n (其中\n是回車符)執行:scanf("%s",name);的時候,由于scanf是讀數據直到看見空白符(空白符:指空格符、制表符、回車符)就停止的輸入函數。所以執行后,把abcd存到了name中。緩沖區于是變成了 : \n1234\n
接下來的執行就有問題了,如果遇到了:scanf("%d",&number);怎么辦?因為遇到了回車符,它并不是一個數字,所以scanf還有一個特性,就是忽略先導的空白符。不管是有幾百個回車也好,幾萬個空格也罷,只要它們連續地出現在緩沖區的開頭,就統統忽略他們。然后再讀有意義的字符。于是1234被讀入number。
回到剛剛,當緩沖區還是:\n1234\n的時候,如果遇到了:scanf("%c",&sex);應該怎么辦呢?你說,那好辦呀,不是說了忽略前導空白符嗎?跳過回車讀’1’呀!想法是好的,可這只針對你的程序這一種情況。如果我編寫的程序就是統計用戶輸入了多少個回車呢?所以對scanf來講跳過前導空白符有個例外,當參數是%c的時候,就把緩沖區的第一個字符返回回去,不管是什么
。
這樣的設計就有個問題,scanf對不同的參數表現出來的特性不一樣。得承認,這是個缺陷,但不是說這樣不好。
這樣的設計至少把發現所有字符的機會交給了用戶,設計者這樣想:如果程序員使用了scanf("%c",…),那他就有必要知道這函數能把回車符讀出來,至于程序員對回車符感不感興趣,那就看他了,不感興趣的話,程序員也一定知道該怎么處理。回到你的程序里。
當執行scanf("%s",name)的時候,要求你從鍵盤輸入,于是你輸入了"abc",然后“回車”。緩沖區里自然而然地是:abc\n scanf把abc拿走了,留下了\n,緩沖區里現在就剩下\n于是,下一個scanf ("%c",&sex); 想當然地讀取了\n
-
關于scanf忽略前導空白符這一點,可以這樣驗證:
寫個程序,用scanf()讀數據,只要不是%c就行。然后輸入的時候,隨便輸入回車、空格、制表符,然后“回車”確認。會發現程序依然提示等待你輸入。就是因為它忽略掉所有前導空白符之后發現緩沖區是空的!于是乖乖地阻塞住,等待你輸入。 -
關于scanf是直到看見空白符結束讀取這一點,如果你是初學C的話,那么很快你就會遇到另一個函數,叫gets()。
程序里如果我們想一次讀入一個英文句子:I am a student.如果你用scanf讀的話,只能讀出"I",想讀出后面的東西要不斷調scanf。此時需要用gets,這個函數不管是什么一律讀進來,直到遇到回車符才停下。總之,各有各的用途,全都熟悉之后,才能在恰當的時候恰當地使用。
以上轉自:http://blog.pfan.cn/katwood/53198.html
最后感謝大牛的分享。
總結
以上是生活随笔為你收集整理的c语言scanf()函数的原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言在不引入第三变量下交换俩数
- 下一篇: c语言运行时隐藏dos窗口