Posted on 2013-01-02 11:48
鑫龙 阅读(3168)
评论(0) 编辑 收藏 引用 所属分类:
linux编程
首先看一下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"); }
|