首先看一下man的scandir 接口定义
int scandir(const char *dir, struct dirent ***namelist,
int(*filter)(const struct dirent *),
int(*compar)(const struct dirent **, const struct dirent **));
|
,从定义来看就不是一个简单的函数,形参里,出现一个三级指针,二个函数指针。它的功能是,扫描名字为dir的目录,把满足filter函数的过滤条件(即filter执行为非0值)的目录项加入到一维指针数组namelist.数组的总长度为返回值n,如果compar不为空,则最终输出结果还要调用qsort来对数组进行排序后再输出。
从scandir的演示代码,我们可以推算出namelist是一个指向一维指针数组的指针。(一维指针数组等同于 struct dirent ** namelist,这里写在三级指针是因为要从函数里改变namelist的值,必须再多做一级)原因可以参考我的函数传值类型的说明。
以下是一个简单扫描 /usr/lib,并且把所有以lib打头的文件扫描到namelist数组的测试程序,这是参考scandir 提供的样例来修改,alphasort是做原始的ASCII码值比较进行排序的
可以看到namelist是完全动态分配的,不仅数组本身是动态分配,而且数组项指向的空间也是动态分配的。
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
//扫描所有的lib打头的文件
int filter_fn(const struct dirent * ent)
{
if(ent->d_type != DT_REG)
return 0;
return (strncmp(ent->d_name,"lib",3) == 0);
}
void scan_lib(char * dir_name)
{
int n;
struct dirent **namelist; // struct dirent * namelist[];
n = scandir(dir_name, &namelist, filter_fn, alphasort);
if (n < 0)
perror("scandir");
else {
while(n--) {
printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
}
}
int main(int argc ,char * argv[])
{
scan_lib("/usr/lib");
}
|