scanf 函式的原理

2021-07-04 10:20:17 字數 1470 閱讀 7980

scanf()函式的原理

想象輸入裝置(鍵盤)連線著乙個叫「緩衝」的東西,把緩衝認為是乙個字元陣列。

當你的程式執行到scanf時,會從你的緩衝區讀東西,如果緩衝區是空的,就阻塞住,等待你從鍵盤輸入。

現在假設你的緩衝區裡有:abcd\n1234\n  (其中\n是回車符)執行:scanf("%s",name);的時候,由於scanf是讀資料直到看見空白符(空白符:指空格符、製表符、回車符)就停止的輸入函式。所以執行後,把abcd存到了name中。緩衝區於是變成了 : \n1234\n

接下來的執行就有問題了,如果遇到了:scanf("%d",&number);怎麼辦?因為遇到了回車符,它並不是乙個數字,所以scanf還有乙個特性,就是忽略先導的空白符。不管是有幾百個回車也好,幾萬個空格也罷,只要它們連續地出現在緩衝區的開頭,就統統忽略他們。然後再讀有意義的字元。於是1234被讀入number。

回到剛剛,當緩衝區還是:\n1234\n的時候,如果遇到了:scanf("%c",&***);應該怎麼辦呢?你說,那好辦呀,不是說了忽略前導空白符嗎?跳過回車讀'1'呀!想法是好的,可這只針對你的程式這一種情況。如果我編寫的程式就是統計使用者輸入了多少個回車呢?所以對scanf來講跳過前導空白符有個例外,當引數是%c的時候,就把緩衝區的第乙個字元返回回去,不管是什麼。

這樣的設計就有個問題,scanf對不同的引數表現出來的特性不一樣。得承認,這是個缺陷,但不是說這樣不好。

這樣的設計至少把發現所有字元的機會交給了使用者,設計者這樣想:如果程式設計師使用了scanf("%c",..),那他就有必要知道這函式能把回車符讀出來,至於程式設計師對回車符感不感興趣,那就看他了,不感興趣的話,程式設計師也一定知道該怎麼處理。回到你的程式裡。

當執行scanf("%s",name)的時候,要求你從鍵盤輸入,於是你輸入了"abc",然後「回車」。緩衝區裡自然而然地是:abc\nscanf把abc拿走了,留下了\n,緩衝區裡現在就剩下\n於是,下乙個scanf ("%c",&***); 想當然地讀取了\n

- 關於scanf忽略前導空白符這一點,可以這樣驗證:

寫個程式,用scanf()讀資料,只要不是%c就行。然後輸入的時候,隨便輸入回車、空格、製表符,然後「回車」確認。會發現程式依然提示等待你輸入。就是因為它忽略掉所有前導空白符之後發現緩衝區是空的!於是乖乖地阻塞住,等待你輸入。

- 關於scanf是直到看見空白符結束讀取這一點,如果你是初學c的話,那麼很快你就會遇到另乙個函式,叫gets()。

程式裡如果我們想一次讀入乙個英文句子:i am a student.如果你用scanf讀的話,只能讀出"i",想讀出後面的東西要不斷調scanf。此時需要用gets,這個函式不管是什麼一律讀進來,直到遇到回車符才停下。總之,各有各的用途,全都熟悉之後,才能在恰當的時候恰當地使用。

scanf函式的原理

scanf 函式的原理 想象輸入裝置 鍵盤 連線著乙個叫 緩衝 的東西,把緩衝認為是乙個字元陣列。當你的程式執行到scanf時,會從你的緩衝區讀東西,如果緩衝區是空的,就阻塞住,等待你從鍵盤輸入。現在假設你的緩衝區裡有 abcd n1234 n 其中 n是回車符 執行 scanf s name 的時...

c語言scanf 函式的原理

想象輸入裝置 鍵盤 連線著乙個叫 緩衝 的東西,把緩衝認為是乙個字元陣列。當你的程式執行到scanf時,會從你的緩衝區讀東西,如果緩衝區是空的,就阻塞住,等待你從鍵盤輸入。現在假設你的緩衝區裡有 abcd n1234 n 其中 n是回車符 執行 scanf s name 的時候,由於scanf是讀資...

scanf 函式的說明

scanf的返回值由後面的引數決定,且返回值為int型 返回值表示成功讀入的資料的個數,如 scanf d d a,b 如果a和b都被成功讀入,那麼scanf的返回值就是2 如果只有a被成功讀入,返回值為1 如果a和b都未被成功讀入,返回值為0 如果遇到錯誤或遇到end of file,返回值為eo...