2013-01-21 27 views
5

這個例子是從K個& [R書爲什麼getchar()僅在行的開頭識別EOF?

#include<stdio.h> 


main() 
{ 
    long nc; 

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

enter image description here

你能解釋我爲什麼這樣工作。謝謝。

^Z^Z不工作(除非它是在一個行的開頭)

enter image description here

TTY EOF性格
+0

看不到這個例子..你能在這裏發佈代碼嗎? –

+4

這是Windows外殼的「特徵」。在Unix上,您可以通過鍵入Ctrl + D兩次在行末輸入EOF;嘗試鍵入Ctrl + Z兩次。 (或重定向來自文件的輸入。) –

+0

鍵入Ctrl + Z兩次或更多無法正常工作 – Vorgin

回答

0

傳統UNIX的解釋是爲了使閱讀無論是緩衝後阻塞read回報在熟的tty行緩衝區內。在新行的開頭,這意味着read返回0(讀取零字節),並且順便說一句,0大小的read是如何檢測普通文件的文件結束條件。

這就是爲什麼在一條線的中間第一EOF只是強制行的開頭是read,不使C運行時庫檢測文件的結束。 兩個EOF連續的字符會產生0大小的讀取,因爲第二個字符會強制應用程序使用空緩衝區爲read

$ cat 
foo[press ^D]foo <=== after ^D, input printed back before EOL, despite cooked mode. No EOF detected 
foo[press ^D]foo[press ^D] <=== after first ^D, input printed back, and on second ^D, cat detects EOF 

$ cat 
Some first line<CR> <=== input 
Some first line <=== the line is read and printed 
[press ^D] <=== at line start, ^D forces 0-sized read to happen, cat detects EOF 

我假設你的C運行時庫模仿上面(有一種^Zkernel32通話水平沒有特殊處理,更不用說系統調用,在Windows上)中描述的語義。這就是爲什麼即使在輸入行的中間,它也可能在^Z^Z之後檢測到EOF。

+0

不,它不會。如果在該行之前還有其他字符,則^ Z^Z或更多不起作用。 – Vorgin

0

只有在輸入的實際結束時,程序纔會讀取EOF。如果你的終端/操作系統/任何只允許文件在行的開頭結束,那麼這就是你會發現它們的地方。我相信這是對老式終端的反擊,數據一次只能傳輸一行(我知道它可以追溯到打卡讀卡器)。

嘗試從您預先準備好EOF中線的文件中讀取數據。你甚至可能會發現有些編輯會讓這很難!你的程序應該和輸入一樣正常工作。

0

EOF指示「文件結束」。一個換行符(這是按Enter鍵時會發生什麼)不是文件的結尾,而是一行的結尾,因此換行符不會終止該循環。

根據操作系統的不同,EOF字符只有在行上第一個字符即Enter之後的第一個字符時纔可用。由於控制檯輸入通常是面向行的,因此係統可能無法識別EOF字符,直到您將其跟隨Enter

0

我碰巧和你有同樣的問題。當我想結束功能getchar()時,我必須輸入2 EOF或輸入<ENTER>加上EOF

這裏還有一個更簡單的答案我搜索了這個問題:

如果進入終端的字符EOF將扮演停止該進入,這將引起進入的一個新的轉折的作用;而如果沒有進入發生,或換句話說,當getchar()正在等待新的輸入時(例如剛剛輸入完畢或EOF),則您即將輸入的EOF等於「結束文件「,這將導致程序停止執行函數getchar()。

PS:當您使用getchar()時會出現問題。我認爲這個答案更容易理解,但也許不適合你,因爲它是從中文翻譯過來的......

相關問題