C语言测试。自己实现scandir 函数
来源:互联网 发布:小米人工智能家庭影院 编辑:程序博客网 时间:2024/06/10 04:47
int(*filter)(const struct dirent *),
int(*compar)(const struct dirent **, const struct dirent **));
,从定义来看就不是一个简单的函数,形参里,出现一个三级指针,二个函数指针。它的功能是,扫描名字为dir的目录,把满足filter函数的过滤条件(即filter执行为非0值)的目录项加入到一维指针数组namelist.数组的总长度为返回值n,如果compar不为空,则最终输出结果还要调用qsort来对数组进行排序后再输出。
#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");
}
从这个样例,我们可以推算出namelist 的数据结构是.另外一个难点是,这个数组是动态形成的。即根据扫描结果来生成数组。这样在函数里构造这样数据结构还是相当有难度。
/*
* Author : Andrew Huang <bluedrum@163.com>
*
*/
#define MAX_DIR_ENT 1024
typedef int(*qsort_compar)(const void *, const void *);
int hxy_scandir(const char *dir, struct dirent ***namelist,
int(*filter)(const struct dirent *),
int(*compar)(const struct dirent **, const struct dirent **))
{
DIR * od;
int n = 0;
struct dirent ** list = NULL;
struct dirent * ent ,* p;
if((dir == NULL) || (namelist == NULL))
return -1;
od = opendir(dir);
if(od == NULL)
return -1;
/* 分配一个最大数组 */
list = (struct dirent **)malloc(MAX_DIR_ENT*sizeof(struct dirent *));
while(( ent = readdir(od)) != NULL)
{
if( filter && !filter(ent))
continue;
p = (struct dirent *)malloc(sizeof(struct dirent));
memcpy((void *)p,(void *)ent,sizeof(struct dirent));
list[n] = p;
n++;
if(n >= MAX_DIR_ENT)
break;
}
closedir(od);
/* 改变返回数组大小*/
*namelist = realloc((void *)list,n*sizeof(struct dirent *));
if(*namelist == NULL)
*namelist = list;
/* 数组排序*/
if(compar)
qsort((void *)*namelist,n,sizeof(struct dirent *),(qsort_compar)compar);
return n;
}
文件:hxy_scandir.zip大小:1KB下载:下载
程序分析
1.这一个程序的第一个难点是 namelist个数不确定的.是根据扫描目录的结果来确定,并且通过返回值告诉调用者.一种办法是做两次循环,先扫描一次readdir从头读一次,确定个数,然后再重新读一次读入内容,这样结果是准确了,但是效率极低.另外一种方法读入时采用是使用链表缓存,然后最后一次性存入数组.这样代码过于复杂了.
最后采用一个折中的办法,即开始一次性分配最大值(1024)的数组,在读入时直接对数组操作.这样代码处理简单,绝大部分情况能正确运行.万一有超过1024,一种是简单丢弃多余,二是扩大最大值.这个方法是在效率和正确性采用一个折衷。
2.最后输出时,可以用realloc调整namelist大小再输出,这样可以节约堆空间。
3.关于最后的数组的排序,scandir文档明确告之是采用qsort进行排序,因此最后需要进行这一步,关键是参数怎么填写。
4.这个函数内部的指针操作相当复杂,象三级指针namelist最好不要直接使用,而是要在函数用一个中间指针变量struct dirent ** list 来简化。而且在函数是直接将其作为数组
转自http://blog.chinaunix.net/uid-9162199-id-108513.html- C语言测试。自己实现scandir 函数
- Linux c 目录操作函数scandir
- Linux c 目录操作函数scandir
- Linux c 目录操作函数scandir
- Linux c目录操作函数scandir
- Linux c 目录操作函数scandir
- scandir 函数
- 自己实现的C 语言的字符串替换函数
- 自己实现的C 语言的字符串替换函数
- 自己实现substr函数——C语言
- 用c语言实现一个自己的atof()函数
- C语言小函数——atol(自己实现)
- 自己编写c语言实现的字符串操作函数
- C语言实现单链表,和测试主函数
- C语言实现串,和简单的主函数测试
- 自己实现C语言库函数
- PHP scandir() 函数
- C语言字符测试函数
- ArcGIS for Android 之callout初级实现
- Oracle事务
- 小结(2013.3.24~2013.4.15)
- JAVA读写改文件(IO)
- 使用ARC时因为循环引用导致内存泄漏
- C语言测试。自己实现scandir 函数
- 设计模式——创建型模式
- 工作感想
- 字符串的系列操作
- APK编译、签名、zipalign优化及APKTOOL的使用
- 关于数据库连接及其配置文件,驱动报错
- Tsar开源:淘宝内部大量使用的系统监控工具
- cxf的wsdl2java命令和JDK的wsimport命令的区别和使用
- 画图计算-- 结构体大小的计算