2012-01-14 134 views
4

手冊頁說:成功的fgets在輸入中遇到EOF時會發生什麼?

與fgets()返回小號,並在錯誤或者雖然沒有字符被讀取時文件的末尾NULL。

我寫調用與fgets,以測試其行爲小C文件。我特別想看看在某些字符輸入後發生EOF時會發生什麼。我在bash上使用了eof組合鍵(Ctrl + D)。我必須按Ctrl + D兩次才能返回fgets。它打印出輸入的字符,直到我按Ctrl + D兩次。一些字符輸入後按Ctrl + D一次完全沒有效果。如果我在此之後輸入了一些字符,它們將存儲在傳遞的數組中。爲什麼fgets的行爲如此?

+2

我不清楚你想了解什麼。當您鍵入Ctrl-D和其他控制組合鍵時,您是否想要了解'fgets'的行爲或終端的典型行爲? – 2012-01-14 11:12:57

回答

6

你描述的行爲與fgets無關。在第二次按ctrl-D之前,shell不會關閉輸入流。

+0

但是如果我先按Ctrl + D而不輸入任何字符,則fgets會返回。在這種情況下,我不需要輸入兩次。 – Bruce 2012-01-14 11:03:02

+2

當前行中沒有字符時,ctrl-D的處理方式會有所不同。在這種情況下,第一次被鍵入時,它會關閉流。請參閱http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29 – 2012-01-14 11:10:07

+0

在解釋行爲的同時,我想知道如果在輸入幾個字符後遇到eof,會發生什麼情況。有沒有一種好的方法來測試這個?更好的是,除了這個行爲是否正確和正式記錄的手冊頁之外,還有其他地方嗎? – batbrat 2012-01-14 11:14:03

4

你會發現,如果輸入結束後至少一些字符讀取,但是遇到新行之前fgets返回非空(的指針提供的緩衝區)和提供的緩衝區將不包含換行符,但將被終止。

這正是fgets所說的文檔。

E.g.

#include <stdio.h> 

int main(void) 
{ 
    char buffer[200]; 

    char* ret = fgets(buffer, sizeof buffer, stdin); 

    printf("exit code = %p\n", (void*)ret); 

    if (ret != 0) 
    { 
     printf("read code = %s<--END\n", buffer); 
    } 

    return 0; 
} 

輸出:

$ printf "no newline here->" | ./a.out 
exit code = 0x7fff6ab096c0 
read code = no newline here-><--END 

或:

$ printf "newline here->\nmore text\n" | ./a.out 
exit code = 0x7fff6f59e330 
read code = newline here-> 
<--END 

上沒有輸入:

$ printf "" | ./a.out 
exit code = (nil) 
2

這就像從文本文件中讀取存儲在磁盤上是不碰巧在最後一個有新的字符線。的fgets()C standard的描述指定它做什麼,包括在這種情況下:

char *fgets(char * restrict s, int n, FILE * restrict stream);

與fgets函數讀取比n所指定的 字符數少至多一個 指向的流到由s指示的數組。在換行符(保留)或文件結束後,不會讀取其他字符 。 A 空字符在最後一個字符讀入 後立即寫入數組中。

fgets()可以給你一個字符串沒有新的行如果輸入線太長,或者如果有前檔案結尾沒有新行。

當您從磁盤文件讀取時,到達文件末尾時會出現文件結束條件。當您從交互式設備(如鍵盤)讀取數據時,文件結束條件觸發的方式不是由C標準規定的。在類Unix系統上,通過在行的開頭鍵入Control-D或在行的中間鍵入Control-D兩次(儘管控制字符可以重新配置)來觸發它。

這是否可能取決於實施。

C99 7.19p2說:

文本流是由成 行字符的有序序列,另外,每個行包括零個或多個字符的 終止換行字符。最後一行是否需要 終止換行字符是實現定義的。

類似Unix的系統通常不需要尾隨的換行符。

相關問題