2011-10-12 105 views
4

一個相關的問題是here,但我的問題是不同的。getchar()和stdin

但是,我想了解更多關於getchar()和stdin的內部信息。我知道getchar()只是最終調用fgetc(stdin)。

我的問題是關於緩衝,stdin和getchar()行爲。鑑於經典ķ& R實施例:

#include <stdio.h> 

main() 
{ 
    int c; 

    c = getchar(); 
    while (c != EOF) { 
     putchar(c); 
     c = getchar(); 
    } 
} 

在我看來,那的getchar()的行爲可以被描述如下:

如果沒有什麼的標準輸入緩衝區,讓OS接受用戶輸入直到按下[enter]。然後返回緩衝區中的第一個字符。

假設程序運行並且用戶輸入「鳳尾魚」。

因此,在上面的代碼清單中,第一次調用getchar()會等待用戶輸入,並將緩衝區中的第一個字符賦給變量c。在循環內部,第一次迭代對getchar()的調用說:「嘿,緩衝區中有東西,返回緩衝區中的下一個字符。」但while循環的第N次迭代導致getchar()說:「嘿,緩衝區中沒有任何東西,所以讓stdin收集用戶輸入的內容。」

我花了一點時間用c源代碼,但它看來這是比較標準輸入,而不是龜etc()的行爲神器。

我錯了嗎?感謝您的見解。

+3

我非常懷疑「經典的K&R例子」有'fflush(stdin)'未定義的行爲!我現在無法檢查...... – pmg

+1

@pmg:你說得對,我糾正了這個例子。 – schot

+0

謝謝,我必須粘貼一個骯髒的例子,其中包含一些來自我的實驗的碎石。 – ybakos

回答

3

我知道getchar()只是最終調用fgetc(stdin)

不一定。 getchargetc不妨擴大到了閱讀的實際過程從文件,以作爲fgetc

int fgetc(FILE *fp) 
{ 
    return getc(fp); 
} 

嘿,沒有什麼在緩衝區中實現的,所以讓標準輸入收集什麼類型的用戶。 [...]它看起來更像是stdin的行爲人造物,而不是fgetc()

我只能告訴你我所知道的,這就是Unix/Linux的工作原理。在該平臺上,一個FILE(包括stdin指向的那個東西)包含一個文件描述符(一個int),該文件描述符被傳遞給操作系統,以指示FILE從哪個輸入源獲取數據以及緩衝區和其他一些簿記內容。

「聚集」部分則意味着「調用文件描述符上的read系統調用以再次填充緩衝區」。不過,這對C的實現有所不同。

+0

感謝您的洞察力。那麼,在高層次上,我對一般行爲的描述是否正確?正如「嘿,緩衝區中沒有任何東西,所以從stdin收集一些新的輸入?」 – ybakos

+0

@ybakos:是的,就是這樣。 'fgetc'實現技巧,btw。不是虛構的:IIRC,我在4.4BSD UNIX C庫中看到了這一點,Mac OS X中最終派生出這個庫。 –

+0

謝謝larsmans。嘖嘖,還有一點要加到你的42k上。 ybakos

5

getchar()的輸入是行緩衝的,輸入緩衝區是有限的,通常是4 kB。您首先看到的是您輸入的每個字符的回顯。當你按下回車鍵,然後getchar()開始返回字符到LF(它被轉換成CR-LF)。當您持續按住沒有LF的按鍵一段時間時,它將在4096個字符後停止回顯,您必須按ENTER繼續。