2017-02-14 78 views
7

這是一個非常基本的C問題,來自Kernighan和Ritchie的第18頁。爲什麼不用getchar()讀取退格字符?

我編譯這個非常簡單的代碼從鍵盤字符計數輸入:

#include <stdio.h> 

/* count characters in input; 1st version */ 
main() 
{ 
    long nc; 

    nc = 0; 
    while (getchar() != EOF) 
    ++nc; 
    printf("%1d\n", nc); 
} 

編譯沒有問題,運行良好,並且行爲與預期相同,即如果我輸入「Hello World」的好看多了,它當我按下CTRLD時,返回值爲11以給出EOF字符。

什麼讓我感到困惑的是,如果我犯了一個錯誤,我可以使用退格刪除這些字符並重新輸入,並且它只返回當我調用EOF時終端顯示的字符數。

如果代碼正在計算每個字符(包括特殊字符),如果我鍵入四個字符,刪除兩個,輸入另外兩個,不應輸出8個字符(4 char + 2 del + 2 char) 4?

我明顯誤解了C如何處理退格,以及代碼如何增加變量nc

+4

編輯由終端應用程序處理,所以'getchar'從不讀取刪除。 –

+0

注意:根據標準,您應該使用'int main(void)'而不是'main()',因爲前者是有效的。 –

+0

@CoolGuy:實際上,第二個版本仍然有效,但遺留下來。這是一個過時的功能,可能會從標準中刪除。說:是的,應該明確使用第一個版本。通常原型風格的簽名應該用於一般的功能。 – Olaf

回答

5

通常,您的終端會話以「行模式」運行,也就是說,當行完成時(例如,您按下了Return等),它僅將數據傳遞到您的程序。所以你只看到這條線,因爲它是完整的(在你的程序看到任何東西之前已經完成了任何編輯)。通常這是一件好事,所以每個程序都不需要處理刪除/ etc。

在大多數系統上(例如基於Unix的系統等),可以將終端設置爲「原始」模式 - 也就是說,每個字符都會按收到的方式傳遞給程序。例如,面向屏幕的文本編輯器通常會這樣做。

5

這並不是說getchar()不會計算「刪除」,但它甚至在終端驅動程序傳遞給您的程序之前不會看到輸入。

當您輸入內容時,直到您按\n或發送EOF(或EOL)時纔會到達您的C程序。這就是POSIX定義的Canonical Mode Input Processing - 這通常是默認模式。

+0

對,我明白了。所以這更多的是我對終端工作原理的誤解,而不是C代碼本身。 –

1

退格字符通常用來編輯熟TTY模式輸入(參見規範輸入模式在BSD tty(4)termios(3)在Linux系統中),所以它們在tty驅動消耗,並且不要在輸入過程之後。這同樣適用於Ctrl-D作爲文件結尾或Ctrl-K作爲終止輸入字符。駕駛員在幕後執行幾件事情,最終沒有得到您的過程。這些都是爲了讓用戶和程序員更容易,因爲通常不需要在你的生活中刪除輸入(這是刪除它的原因),或者希望行結束爲\n而不是\r,因爲tty通常會生成按[RETURN]鍵。但是如果你從一個恰好有退格的文件中讀取數據,你將會把它們當作正常的輸入,只要創建一個帶有退格的文件並嘗試讀取重定向輸入,就可以在輸入中看到這些字符。順便說一下,如果你想在終端生成退格,只需在每個字符前加上一個Ctrl-V字符(這也是在tty驅動中管理的,從文件讀取時不會發生),你會看到你的退格字符作爲文件中的正常輸入(發送Ctrl-V只是它的兩倍)

相關問題