我在写我的第一个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语句来检查,看看是否该文件是一个头?
简单地检查文件的扩展名是.h
,是这样的:
const char *ext = strrchr (entry->d_name, '.');
if ((ext != NULL) && (!strcmp (ext+1, "h"))) {
// header file
}
Ofcourse,请注意,这是假定所有的头文件有一个.h
扩展,这可能会或可能不会是真实的,C标准并不要求头文件必须有一个.h
扩展。
每个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++;
有一些不是检查的文件扩展名更好的方法。
维基百科有一个很好的文章在这里和这里 。 后者想法被称为魔术号码数据库,其基本上意味着,如果一个文件包含嗒嗒序列然后它在数据库中列出的匹配类型。 有时数对位置的限制,有时它不。 此方法是IMO虽然比文件扩展检测慢更准确。
不过话又说回来了,换作检查,看看它的标题简单的事情,这可能是一个有点矫枉过正的XD
您可以检查是否最后几个字符是头文件扩展名,.H,.HPP之一,等使用dirent
结构的d_name
的文件的名称。
或者,你可以运行“文件”命令,并解析其结果。
你可能只是想检查的文件扩展名。 使用的dirent ,你会想看看d_name
。
随你(由你决定。
最简单的办法是只看文件名(d_name),并检查是否有类似“.H”或“.HPP”或任何结束。
打开文件,实际上阅读它,看它是否是有效的C / C ++,在另一方面,将会有很多更复杂的...你可以通过编译器运行它,但不是每头能独立工作,从而使测试会给你很多的假阴性。