Re: [問題] C用法的限制???

看板C_and_CPP作者 (我不配)時間16年前 (2009/11/20 22:36), 編輯推噓4(513)
留言9則, 6人參與, 最新討論串2/2 (看更多)
回覆上篇推文

11/20 20:43,
其實小弟我不懂的是, Enter塞回去給下一個讀的狀況, 那
11/20 20:43

11/20 20:44,
我後面如果都是讀數字的scanf為什麼就不會Enter塞住??
11/20 20:44

11/20 20:44,
應該有些人有經驗, 要讀數字時餵英文字, 就塞爆了@_@"
11/20 20:44
scanf() 每次執行後,會先去輸入緩衝區 (input buffer) 找看看有沒有內容 如果是空的(內含透明字視為空),就會等候使用者的按鍵輸入, 直到 enter 被按下才結束。 這個 enter 在輸入緩衝區會紀錄為 '\n' 即 0xa (是 Windows;Linux 未測)。 今天假設使用者輸入『123 456』然後按下 enter,則輸入緩衝區值為『123 456\n』。 scanf 會從緩衝區的第一個字元開始,跟其參數1傳來的字串值做比對 (match), 只有在 match 時,才從緩衝區刪除該字串。 換言之,比對規則不管是 scanf("123"); 或 scanf("%d", &number1); 都會跟緩衝區裡的『123』做比對成功,然後刪掉比對成功的字串值, 使得新的緩衝區變成『 456\n』。 再接著執行 scanf("%d", &number2); 時,同樣會從第一個字元「半形空白」開始比對。 而「半形空白、tab、enter」被歸類為透明字元,處理時一律會被忽略。 因此 number2 能抓到 456 這個值。 今天如果把緩衝區第一個字元,由半形空白換成全形空白, 則跟整數做比對的結果會是失敗的。 因此 number2 最終沒有改變數值,輸入緩衝區同樣也沒有變動,兩者皆維持原狀。 == 同理 int x=-1, y=-1; scanf("%d", &x); scanf("%d", &y); 第一次 scanf 執行時 假設使用者輸入『123』還有『tab』還有『enter』, 即輸入緩衝區為『123\t\n』。 結果是 123 比對成功,新的緩衝區為『\t\n』這兩個透明字元。 第二次 scanf 執行時 之前的透明字元都被忽略,因此系統會再次等待使用者輸入內容。 即使兩次 scanf() 函數中間,放入一個 getchar(); 也不會改變結果, 這個 getchar() 會抓到 '\t' (0x9) 的值。 == 上一篇文章解決方法之一,就是把輸入緩衝區的垃圾值沖掉 (flush) 可以這樣做 char val; do{ val = getchar(); }while(val != '\n'); 執行完此迴圈後,緩衝區內的 enter 就會被吃光光了。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 124.8.149.40 ※ 編輯: twotwoone 來自: 124.8.149.40 (11/20 22:40) 潤飾一下句子。 ※ 編輯: twotwoone 來自: 124.8.149.40 (11/20 23:14)

11/20 23:10, , 1F
看來就是差在透明字的處理, 感謝221大....<(_ _)>
11/20 23:10, 1F

11/20 23:12, , 2F
其實有code能實際trace一遍的話就不會模糊到現在了Orz
11/20 23:12, 2F

11/20 23:49, , 3F
推一個 解釋的非常詳細 :)
11/20 23:49, 3F

11/21 00:14, , 4F
去 google search 找 libc/stdio/vfscanf.c
11/21 00:14, 4F

11/21 00:14, , 5F
一些怪用法都是從裡面找到的.... XD
11/21 00:14, 5F

11/21 02:39, , 6F
補充 *scanf的參數只有 %c 不會略過透明字(whitespace)
11/21 02:39, 6F

11/21 02:59, , 7F
原來還有這個例外,感謝!
11/21 02:59, 7F

11/21 08:44, , 8F
啊 是 google code search .... orz
11/21 08:44, 8F

01/09 13:32, , 9F
01/09 13:32, 9F
文章代碼(AID): #1B1gbPpZ (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1B1gbPpZ (C_and_CPP)