2

我正在编写我的第一个 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 语句来检查文件是否是标题?

4

6 回答 6

3

只需检查文件扩展名是否为.h,例如:

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

当然,请注意,这假设您的所有头文件都有.h扩展名,这可能是也可能不是,C 标准不要求头文件必须具有.h扩展名。

于 2012-09-05T06:36:03.200 回答
2

有一些比检查文件扩展名更好的方法。

维基百科在这里这里有一篇很好的文章。后一种想法被称为幻数数据库,这实质上意味着如果一个文件包含 blah 序列,那么它就是数据库中列出的匹配类型。有时数字对位置有限制,有时则没有。这种方法 IMO 更准确,尽管比文件扩展名检测慢。

但是话又说回来,对于像检查它是否是标题这样简单的事情,这可能有点矫枉过正 XD

于 2012-09-05T06:58:53.907 回答
2

每个dirent结构都有一个d_name包含文件名的文件,所以我想看看它是否遵循某种模式,比如以.hor结尾.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,但幸运的是他们是少数。

你甚至可能想考虑一个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++;
于 2012-09-05T06:34:52.623 回答
1

您可以检查最后几个字符是否是头文件扩展名之一,.h、.hpp 等。使用dirent结构d_name作为文件名。

或者,您可以运行“文件”命令并解析其结果。

于 2012-09-05T06:33:52.813 回答
0

您可能只想检查文件扩展名。使用dirent,你会想看看d_name.

于 2012-09-05T06:35:12.920 回答
0

这取决于你。

最简单的方法是只查看文件名 (d_name),然后检查它是否以“.h”或“.hpp”之类的结尾。

另一方面,打开文件并实际读取它以查看它是否是有效的 c/c++ 会复杂得多...您可以通过编译器运行它,但并非每个标头都可以独立运行,因此测试会给你很多假阴性。

于 2012-09-05T06:35:29.800 回答