2011-04-21 185 views
14

在一個項目中我必須做C89標準,我必須檢查一個文件是否存在。 我該怎麼做?C檢查文件是否存在

我想用

FILE *file; 
if ((file = fopen(fname, "r")) == NULL) 
{ 
    printf("file doesn't exists"); 
} 
return 0; 

的,但我認爲可以有更多的情況下,則文件不存在,將做的fopen == NULL。

我如何做到這一點?我寧願不使用包含而不是。

+1

如果'fopen()'失敗(即返回'0'),則不必(不能!)關閉文件句柄。如果成功,你必須這樣做。 – Mario 2011-04-21 14:17:13

+1

我不認爲在C89標準中有更好的方法。如果您允許POSIX或其他標準,請參閱http://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform – interjay 2011-04-21 14:17:44

回答

14

如果你不能在你的環境中使用stat()(這肯定是更好的方法),只需評估errno即可。不要忘記包含errno.h。

FILE *file; 
if ((file = fopen(fname, "r")) == NULL) { 
    if (errno == ENOENT) { 
    printf("File doesn't exist"); 
    } else { 
    // Check for other errors too, like EACCES and EISDIR 
    printf("Some other error occured"); 
    } 
} else { 
    fclose(file); 
} 
return 0; 

編輯:忘了FCLOSE封裝成別的

+0

- 1對於ENOENT,'ENOENT'不像標準C89那樣是OP要求的,其實現的定義並不保證存在。 C89:「附加的宏定義,以E開頭,一個數字或E和一個大寫字母,也可以由實現指定。」 – Wiz 2011-06-02 05:45:25

+0

你說得對,這不符合標準(我想我有很好的理由)。如果代碼應該100%可移植到所有C89實現中,這不是正確的方法。另一方面,對ENOENT的支持是廣泛可用的,因此使用上述方法通常不是一個壞主意。除非你的平臺是一個非常特殊的平臺(嵌入式系統等)。如果fopen返回-1並忽略特定的錯誤,那麼也可以簡單地保釋出來,就像問題中給出的例子一樣。 – onitake 2011-06-24 20:20:48

+0

「ENOENT」+1。它符合POSIX標準,比使用'stat'更好,因爲這可能會導致競爭條件和安全問題。 – 2012-05-20 20:09:11

1

我想這與系統環境(如POSIX或BSD)有關,而不是您使用的C語言版本。

在POSIX中有一個stat()系統調用,可以爲您提供有關文件的信息,即使您無法讀取它。但是,如果文件位於沒有訪問權限的路徑中,則無論文件是否存在,文件總是會失敗。

如果您無法訪問該路徑,則永遠不應該查看包含的文件。

3

這是不可能的純ISO檢查存在了某些標準C. 有沒有真正的好移植的方法來確定一個文件名爲 是否存在;你可能不得不求助於系統特定的方法。

2

這不是一個便攜式的東西,所以我會給你操作系統特定的調用。

在Windows中,您使用GetFileAttributes並檢查-1返回(INVALID_HANDLE或類似的東西)。

在Linux中,您有fstat來執行此操作。然而,大多數時候,我只是做文件打開技巧來測試,或者只是繼續使用該文件並檢查異常(C++/C#)。

1

你真的要訪問的文件嗎?在unistd.h中,通過 訪問(文件名,F_OK)== 0,檢查通常會更好,而且我認爲這是非常寬泛的標準。