2009-11-23 34 views
31

你如何看到最後一張照片?換句話說,要爲EOF投入什麼?我檢查了定義,它說EOF是-1。什麼是C編程語言中的EOF?

如果您輸入Ctrl-D,則不會看到任何內容。

#include <stdio.h> 

int main() { 
int c; 
while((c = getchar() != EOF)) { 
    printf("%d\n", c); 
} 
printf("%d - at EOF\n", c); 
} 
+0

你介意澄清一下嗎?你的問題是什麼? – qrdl 2009-11-23 09:41:39

+0

我想放進EOF並看到printf(「%d - at EOF \ n」,c); – 2009-11-23 09:45:41

+0

和EOF被認爲是-1,但它解釋爲三個字符並且輸出三個1的 – 2009-11-23 09:46:41

回答

40

在Linux系統和OS X,字符輸入到引起EOF是Ctrl鍵 - d。對於Windows,它是Ctrl - Z

根據操作系統的不同,只有該字符是行上的第一個字符,即後的第一個字符,才能使用輸入。由於控制檯輸入通常是面向行的,因此係統可能無法識別EOF字符,直到您按照輸入

是的,如果該字符被識別爲EOF,那麼你的程序永遠不會看到實際的字符。相反,C程序將從getchar()獲得-1

+0

好的,但在Windows上Ctrl-z和Ctrl-D有什麼區別? Ctrl-z = EFO Ctrl-D = kill? – 2009-11-23 10:14:28

+0

@ Chris_45:在Windows上,Ctrl-Z標記EOF,Ctrl-D只是Ctrl-D(或字符04)。 @ gotch4:標準(但很少使用)HTML:< kbd >。 – 2009-11-23 11:50:16

+1

@ Chris_45:Ctrl-D對應於ASCII EOT(傳輸結束),但MS-DOS使用Ctrl-Z(ASCII SUB)與CP/M兼容,並且Windows繼承該選項。在CP/M中,EOF字符實際上是文件中的一個字符,因爲所有文件必須是128個字符的倍數。用於信號EOF的字符特定於操作系統而非編程語言。 http://en.wikipedia.org/wiki/End-of-file – Clifford 2009-11-23 14:15:11

4

EOF表示文件結束。這是一個跡象表明文件已到達,並且不再有數據。

編輯:

我認錯。在這種情況下,它不是文件的結尾。如前所述,它在CTRL + d(linux)或CTRL + z(窗口)傳遞時傳遞。

+1

-1:它可能意味着發生錯誤。 – 2009-11-23 09:43:27

+0

編輯不正確。短語「CTRL + d ...被按下時傳遞」是無稽之談。當用戶輸入ctrl-D時,輸入文件關閉,'getchar'返回EOF,表示文件已到達。沒有發送到進程的EOF字符。 – 2013-01-09 22:47:52

+0

你是什麼意思這是一個標誌?它是一種特定的位模式嗎? – 2015-01-11 12:09:36

7

EOF的值是一個負整數,以區別於0到255範圍內的「char」值。它通常是-1,但它可以是任何其他負數......根據POSIX規格,所以你不應該認爲它是-1。

^D字符是您在UNIX/Linux上的控制檯流中鍵入的內容,以告訴它在邏輯上結束輸入流。但在其他情況下(例如,當您從文件中讀取時),它只是另一個數據字符。無論哪種方式,^ D字符(意味着輸入的結尾)永遠不會使它成爲應用程序代碼。

As @Bastien說,如果getchar()失敗,EOF也會返回。嚴格地說,您應該調用ferrorfeof來查看EOF是表示錯誤還是流結束。但在大多數情況下,您的應用程序在任何情況下都會執行相同的操作

+0

所以你永遠不能讓win32上的EOF使它到應用代碼並看到最後一個打印? – 2009-11-23 09:53:00

+0

@ Chris_45 - 我正在談論EOF的含義。在你的「appcode」中的bug的根本原因是完全不同的 - 參見@盧卡斯的回答, – 2009-11-23 21:33:12

+0

在stdio.h中有'#define EOF(-1)' – 2016-01-23 12:36:37

26

您應該將括號改爲

while((c = getchar()) != EOF) 

因爲「=」操作符比「!=」運算符優先級較低。然後你會得到預期的結果。你的表情等於

while (c = (getchar()!= EOF)) 

你得到兩個1的作爲輸出,因爲你在做比較「C!= EOF」。這將始終成爲您輸入的字符,然後通過點擊返回的「\ n」。除了最後一個比較,其中c真的是EOF,它會給你一個0.

關於EOF的編輯:EOF通常是-1,但這不是標準保證的。該標準僅在第7.19.1定義有關EOF:

EOF它將擴展爲一個整數 常量表達式與int類型和 負值,即由幾個 函數返回,以指示 結束文件,即從流中不再輸入 ;

假設EOF等於-1是合理的,但是當使用EOF時,您不應該針對特定值進行測試,而應使用宏。

+4

我們有一個贏家。 – Pod 2009-11-23 11:02:39

+1

很好的補充關於並不總是-1 ..大多數人忽視 – 2009-11-23 14:24:28

+0

「擴展爲整數常量表達式,類型爲int和負值的EOF」「Int」是32位,EOF信號通常取決於wchar_t值-1(或65535)或char值-1與一個無關* * *。 – 2016-01-23 04:25:23

4

夫婦錯別字:

while((c = getchar())!= EOF)

代替:

while((c = getchar() != EOF))

另外的getchar()把一個返回鍵爲有效輸入,所以你需要緩衝它too.EOF是標記以指示輸入結束。一般來說,它是一個所有位設置的int。


#include <stdio.h> 
int main() 
{ 
int c; 
while((c = getchar())!= EOF) 
{ 
    if(getchar() == EOF) 
    break; 
    printf(" %d\n", c); 
} 
    printf("%d %u %x- at EOF\n", c , c, c); 
} 

打印:

49 
50 
-1 4294967295 ffffffff- at EOF

輸入:

 
1 
2 
<ctrl-d> 
+2

您的代碼中是否存在錯誤?你調用'getchar()'兩次(一次在while循環中,一次在if中),所以第二個輸入將會丟失。 – Heinzi 2009-11-23 10:48:56

+0

你測試過這個工作嗎?你正在調用getchar兩次.. – Pod 2009-11-23 11:03:47

+0

它的工作原理是因爲第二個getchar()從返回得到'\ n'。 – Lucas 2009-11-23 11:11:23

1
#include <stdio.h> 

int main() { 
    int c; 
    while((c = getchar()) != EOF) { //precedence of != is greater than =, so use braces 
     printf("%d\n", c); 
    } 
    printf("%d - at EOF\n", c); 
} 

我覺得這是檢查EOF的值正確方法。 我檢查了輸出。

輸入:ABC和輸入我OUTPUT:97 98 99 10(ASCII值)

輸入按Ctrl-d我OUTPUT:-1 - 在EOF。 所以我認爲-1是EOF的值。

嘗試其他輸入而不是Ctrl-D,如Ctrl-Z。 我認爲它因編譯器而異。

+1

當然,'stdio.h'將'EOF'定義爲'-1'。但這不應該讓你感興趣,也不需要看它或打印出來。只需在代碼中檢查EOF,並讓編譯器擔心細節。 – 2009-11-23 11:57:38

3

從終端輸入不會真的「結束」(除非設備已斷開連接),但在終端中輸入多個「文件」是有用的,因此鍵序列被保留以指示輸入結束。在UNIX中,按鍵到EOF的轉換由終端驅動程序執行,因此程序不需要將終端與其他輸入文件區分開來。默認情況下,驅動程序將行開頭的Control-D字符轉換爲文件結束指示符。要在輸入流中插入一個實際的Control-D(ASCII 04)字符,用戶在其前面加上一個「quote」命令字符(通常是Control-V)。 AmigaDOS類似,但使用Control- \而不是Control-D。

在微軟的DOS和Windows(以及在CP/M和許多DEC操作系統中),從終端讀取將永遠不會產生EOF。相反,程序認識到源是終端(或其他「字符設備」),並將給定的保留字符或序列解釋爲文件結束標誌;通常這是一個ASCII Control-Z代碼26.一些MS-DOS程序,包括Microsoft MS-DOS shell(COMMAND.COM)和操作系統實用程序(如EDLIN)的一部分,將一個Control-Z在文本文件中標記有意義數據的結尾,和/或在寫入文本文件時將Control-Z追加到最後。這樣做有兩個原因:

  1. 與CP/M的向後兼容性。 CP/M文件系統只記錄了多個128字節「記錄」的文件長度,因此按照慣例,如果有意義的數據結束於記錄中間,則使用Control-Z字符標記有意義的數據的結尾。 MS-DOS文件系統一直記錄文件的確切字節長度,所以這在MS-DOS上是不需要的。

  2. 它允許程序使用相同的代碼從終端和文本文件讀取輸入。

-1
#include <stdio.h> 

int main() { 
    int c; 
    while((c = getchar()) != EOF) { 
     putchar(c); 
    }  
    printf("%d at EOF\n", c); 
} 

改性上面的代碼,得到更清楚地說明EOF,按下Ctrl + d和的putchar用於打印用printf while循環內的炭避免。

+0

在Ubuntu 14.04上測試過 – 2016-06-07 06:08:32

-1
int c; 

while((c = getchar())!= 10) 
{ 
    if(getchar() == EOF) 
     break; 

    printf(" %d\n", c); 
}