2017-03-12 21 views
1

對於我的計劃,我有一個提示到標準輸出在輸入行中間使用EOF?

> 

,然後我的程序從標準輸入讀取。如果EOF尚未到達,則提示會循環。如果我輸入的東西,比如我已經注意到:

> bee 

當我按下CTRL-d一次,沒有任何反應。當我再次按下CTRL-D時,我的提示再次出現。只有當我第三次按它時,我的程序會因EOF而終止。這是否意味着我的代碼有問題?或者這是正常的行爲?

下面有一個簡化版本的我的代碼:

(fopen used) 
(print prompt) 
while((fgets(tester, 1026, input)) != NULL) { 
    if(there is a # in tester) { 
    (print prompt)   
    continue; 
    } 
} 
+1

代碼中的問題? – Shark

+0

'Ctrl + D'(Linux)或'Ctrl + Z'(Windows)必須是'newline'後面的第一個按鍵。但是,我仍然注意到類似的好奇心,這是我無法解決的。 –

+1

這種僞代碼混合不能編譯,似乎解析的唯一部分有一個括號不匹配。請發佈一個最小的完整示例。 – dlatikay

回答

0

在UNIX終端,CTRL-d不做任何事情不是立即或多或少發送在終端中輸入緩衝器未決所有的字節。


背景:

通常情況下,當你輸入的東西到你的終端,這些東西是行緩衝,所以你可以繼續編輯一條線,直至您滿意,然後將其發送到通過輸入換行符(或CTRL-D,不同之處在於CTRL-D不會在末尾添加換行符)來運行進程。

現在,進程通過檢查read()調用是否返回任何內容來檢測輸入流的結束。因此,如果在空輸入緩衝區上按CTRL-D,則read()調用將返回任何內容,並且進程認爲「沒有更多字節從此流中傳出,我最好不要再嘗試」。 Afaik沒有其他方法來檢查輸入流的結束,因此所有識別的程序都可以直接或通過標準C庫執行此操作。後者是您在撥打fgets()時所做的。


您的情況:

  1. 第一CTRL-d僅僅發送三個大字 「蜜蜂」 到你的過程。呼叫fgets()中的read()呼叫將返回這三個字符,並且您的fgets()實施將檢查換行符。由於它沒有發現,並且由於其自己的輸出緩衝區尚未滿,它立即繼續通過另一個read()調用獲取更多字符。

  2. 第二個CTRL-D沒有發送任何內容,因爲自上次CTRL-D以來沒有輸入任何其他字符。 write()調用返回時沒有輸出,fgets()發現它接收到零個字符並將其稱爲EOF條件。所以它返回給您(大部分緩衝)的字符串"bee"

    您的程序可能會檢查該字符串是否包含#字符。但是它的循環不能終止,直到fgets()調用返回NULL(沒有break語句來初步離開循環)。

  3. 第三個CTRL-D再次向您的進程發送零字節。這導致第二個fgets()調用的第一個read()調用返回零字節(循環將在第一次迭代成功後重新輸入)。 fgets()實現看到空的結果,並且因爲它發現它還沒有收到任何字節,它將返回NULL。你的循環條件看到NULL並終止循環,這又導致你的main()返回,退出該過程。


TL; DR:

是的,這完全是正常現象,即使它似乎相當反直覺。這就是UNIX:這是KISS,不一定直觀。