2012-09-05 105 views
1

我正在編寫我的第一個C程序,儘管我來自C++背景。檢查一個文件是否是C中的特定類型

我需要迭代文件目錄並檢查文件是否爲頭文件,然後返回計數。

我的代碼如下,它很簡陋,我認爲:

static int CountHeaders(const char* dirname) { 

    int header_count = 0; 
    DIR* dir_ptr; 
    struct dirent* entry; 

    dir_ptr = opendir(dirname); 

    while((entry = readdir(dir_ptr))) 
    { 
     if (entry->d_type == DT_REG) 
     { 
      //second if statement to verify the file is a header file should be??? 
      ++header_count; 
     } 
    } 

    closedir(dir_ptr); 

    return header_count; 
} 

這將是一個很好的if語句來檢查,看看是否該文件是一個頭?

+2

您不能肯定地告訴我們,如果一個文件是頭文件或不見,也不當查看擴展名或通過文件內容時。 – scai

回答

1

您可以檢查最後幾個字符是否爲頭文件擴展名之一.h,.hpp等。使用dirent結構的d_name作爲文件的名稱。

或者,您可以運行「文件」命令並解析其結果。

+0

如果有很多文件,使用外部命令不是非常有效,並且檢查擴展不能用於例如C++標準庫頭文件。但個人而言,我會在測試其他常見的頭文件擴展名之前,先檢查擴展名,以「.h」開頭。 –

+0

@JoachimPileborg,我同意你的外部命令。 'file'命令可以告訴你它是C代碼,不一定是頭文件,所以它非常有效,效率不高。 –

2

每個dirent結構具有包含文件名的d_name,所以我會看看是否跟隨一些模式,比如在.h.hpp結束。

這將是沿行代碼:

int len = strlen (entry->d_name); 
if ((len >= 2) && strcmp (&(entry->d_name[len - 2]), ".h") == 0)) 
    header_count++; 
if ((len >= 4) && strcmp (&(entry->d_name[len - 4]), ".hpp") == 0)) 
    header_count++; 

當然,這不會從調用它們的可執行文件ha_ha_fooled_you.hpp趕上真正邪惡的人,但thanfkfully他們是少數。

你甚至可能要考慮一個endsWith()功能,使您的生活更輕鬆:

int endsWith (char *str, char *end) { 
    size_t slen = strlen (str); 
    size_t elen = strlen (end); 
    if (slen < elen) 
     return 0; 
    return (strcmp (&(str[slen-elen]), end) == 0); 
} 
: 
if (endsWith (entry->d_name, ".h")) header_count++; 
if (endsWith (entry->d_name, ".hpp")) header_count++; 
+0

在這一點上,你可能想要聲明一個帶有擴展名的NULL結束數組,比如:'{「.h」,「.hpp」,NULL}' – tadman

+0

是的,複雜性沒有終點你可以添加,但我最好在這裏停下來,以免我的答案成爲一篇文章:-) – paxdiablo

+0

@tadman:Q被標記爲'c',所以它*可以被假定爲*該頭文件不會被命名爲'.hpp'。 –

0

你可能只是想檢查的文件擴展名。使用dirent,你會想看看d_name

0

這取決於你。

最簡單的方法是查看文件名(d_name),並檢查它是否以「.h」或「.hpp」或其他類似結尾。

打開文件並實際讀取文件以查看其是否有效c/C++另一方面將會更復雜......您可以通過編譯器運行它,但不是每個頭文件都可以自行運行,這樣測試會給你很多的錯誤否定。

2

簡單的檢查文件的擴展名是.h,一樣的東西:

const char *ext = strrchr (entry->d_name, '.');  
if ((ext != NULL) && (!strcmp (ext+1, "h"))) { 
    // header file 
} 

Ofcourse,請注意,這是假定所有的頭文件有.h擴展,這可能會或可能不會是真實的,C標準的確不要求頭文件必須有.h擴展名。

+0

這將工作,但我會在執行'strcmp'前檢查'ext' agianst NULL指針。否則'boom_crash_segv'文件會給你帶來一些麻煩:-) – paxdiablo

+0

@paxdiablo:的確,'strrchr()'後的'NULL'指針檢查是**必須** :) –

+0

添加NULL檢查,請驗證並確認或濫用:-) – paxdiablo

2

有一些比檢查文件擴展名更好的方法。

維基百科有一篇好文章herehere。後者的想法被稱爲幻數數據庫,這基本上意味着如果一個文件包含等值序列,那麼它就是數據庫中列出的匹配類型。有時候,這個號碼對地點有限制,有時它沒有。這種方法IMO比文件擴展檢測更準確,儘管速度更慢。

但話又說回來,如檢查,看看它的標題簡單的事情,這可能是有點大材小用XD的

+0

有沒有一個C的方式做到這一點?需要哪些庫來做到這一點? – msumaithri

+0

@msumaithri一些快速的谷歌搜索結果:http://linux.die.net/man/3/libmagic – chacham15

相關問題