2012-08-14 63 views
7

這是我的代碼。我使用終端在ubuntu上運行它。當我在終端輸入(a CtrlD)時,程序沒有停止,但仍繼續等待我的輸入。ctrl-d沒有停止while(getchar()!= EOF)循環

是不是CtrlD等於unix中的EOF?

謝謝。

#include<stdio.h> 

main() { 
    int d; 
    while(d=getchar()!=EOF) { 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
     printf("EOF:%d\n", EOF); 
    } 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
} 
+1

這不是遞歸。這只是一個無限循環,直到您停用輸入。遞歸=函數直接調用自己或者在一些其他中間數量的步驟之後。 – 2012-08-14 00:52:02

+0

用gcc編譯,點擊'^ D'停止循環。 – 2012-08-14 01:02:39

+0

@JonLin只需輸入^ D。它也適用於我。但是,當輸入是(a^D)時,循環沒有停止。 – Sam 2012-08-14 01:11:26

回答

11

EOF不是字符。 EOFgetchar()在到達輸入結尾或遇到某種錯誤時返回的宏。 ^D不是「EOF字符」。當你在線上單擊^ D時,在linux下發生的事情是它關閉了流,並且getchar()調用到達輸入的末尾並返回EOF宏。如果在某行的中間鍵入^D,則該流不會關閉,因此getchar()會返回它讀取的值,並且您的循環不會退出。

查看stdio section of the C faq有更好的描述。

此外:

在現代系統中,它沒有反映在文件中存儲任何實際的檔案結尾字符;這是一個信號,沒有更多的字符可用。

+0

我仔細閱讀了網站。在我看來,如果我在一行中間的某處輸入'^ D',bash將處理'^ D'。結果,C程序沒有得到關閉流的命令。如果我在一行中輸入'^ D',C程序將得到正確的命令。我對嗎? – Sam 2012-08-14 01:34:14

+1

@qingfeng這裏有更多關於'^ D'的信息:http://www.c-faq.com/stdio/eofval.html但是,如果它本身並不在線,那麼它就不會被封閉。此處簡短說明:http://stackoverflow.com/a/1516177/851273 – 2012-08-14 01:38:22

+6

當終端處於規範模式時,線路不會通過tty設備傳輸,直到您按下回車鍵。按下配置的EOF鍵(默認情況下爲^ D)將導致數據立即傳輸,並且任何等待它的「read」返回可用字符數。如果該行上已經有數據,這將是一個正常的,非零長度的讀取。如果該行爲空,這將導致零長度讀取,這是文件描述符上的文件結束狀態的* definition *。因此,stdio層會將其解釋爲EOF狀態。 – 2012-08-14 02:06:23

6

除了Jon Lin對EOF的回答,我不確定你寫的代碼是你的意圖。如果你想看到的變量dgetchar返回的值,你需要改變你的while聲明:

while((d=getchar())!=EOF) { 

這是因爲運營商的不平等比分配更高的優先級。因此,在您的代碼中,d將始終爲01

+0

你這麼一絲不苟。但是我只想驗證'd = getchar()!= EOF'這個表達式是0還是1. – Sam 2012-08-14 01:40:13

+0

@Sam:你可以清楚地說明你正在通過寫入來分配比較結果:'while((d =(getchar()!= EOF))!= 0)或者while((d =(getchar()!= EOF)))'這樣編譯器不會向你發出警告。更常見的選擇是'while((d = getchar())!= EOF)',它將'getchar()'的結果賦值給'd',然後將其與EOF進行比較。這樣可以避免編譯器警告。許多現代編譯器會爲你寫的內容產生警告。 – 2017-03-25 00:02:54