列出指定目录中的所有文件名

这个例子主要完成的功能是:列出所给目录及其子目录下的所有文件的名字及其对应的路径名。
/*
 * =====================================================================================
 *
 *       Filename:  BianLi.c
 *
 *    Description:  遍历目录并输出文件名
 *
 *        Version:  1.0
 *        Created:  2011年07月27日 15时33分12秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:   (), 
 *        Company:  NDSL UESTC
 *
 * =====================================================================================
 */
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <dirent.h>
#include    "ourhdr.h"

void func(char *);
void find(char *);

int main(int argc, char **argv)
{
    if (argc != 2){      printf("argument error.\n");  return(0);}//函数运行时需要一个参数即指定的目录

    func(argv[1]);
    return(0);
}

static  char *fullpath;            //fullpath指向全路径名的内存空间
const   int pathmax=1024;          //pathmax是给路径名分配空间时最大的路径名长度

void func(char *pathname)
{1、这个函数主要完成pathname的安置工作
    fullpath = malloc(pathmax + 1);//给指定的路径名pathname分配内存空间
    memset(fullpath, 0 ,pathmax+1);//给内存空间置0
    strcpy(fullpath, pathname);    //把pathname拷到刚刚分配的空间内
    find(fullpath);                //调用这个程序的核心函数find()
}
find的流程:
如果fullpath指向的是一个普通文件,则打印文件名及其路径名接着退出函数;
如果fullpath指向的是一个目录文件,则
1:在该路径(目录)后加上“/”,ptr指向新的路径的末尾;
2:循环该新路径名中的文件,递归调用find函数。

void find(char *fullpath)
{
    struct  stat        statbuf;  //statbuf用以存放文件的相关信息,来判断一个指定路径名是文件还是目录
    DIR     *dp;                  //调用opendir函数时返回的值,opendir返回打开指定目录名的一个目录流的指针(指针类型为DIR),这个流指向目录的第一个入口
    struct  dirent      *dirp;   //struct dirent readdir(DIR *dp),readdir返回一个dirent结构的指针,该指针是dp指向的目录流的下一个目录入口的指针
    char    *ptr;

    if( lstat(fullpath, &statbuf) < 0)    //获得fullpath指向的文件信息,存放在statbuf
    {   printf("stat error.\n");        return;    }
  
    if ( S_ISDIR(statbuf.st_mode) == 0){  //判断该fullpath指向的文件是目录文件还是普通文件,如果是普通文件则执行if语句中的语句
        printf("the filename is %s\n", fullpath);        return;    }
    if ( (dp = opendir(fullpath)) == NULL)//opendir打开fullpath
    {   printf("opendir error.\n");        return;    }//opendir出错了
    ptr = fullpath + strlen(fullpath);    //执行本语句前,fullpath指向的位置因情况而异,执行本句后,fullpath指向fullpath的最后一个位置
    *ptr++ = '/';                         //该语句相当于:*ptr='/';ptr++;     
    *ptr = 0;                             //给ptr一个结尾,这三句的意思是:既然这个fullpath指向的是一个路径名,则把此路径名加上一个/,以便再次判断该目录下面的文件
    while ( (dirp = readdir(dp)) != NULL)
    {     
        if (strcmp(dirp->d_name, ".") ==0 || strcmp(dirp->d_name, "..") == 0)   continue; //忽略"."和".."文件
        strcpy(ptr, dirp->d_name);        //此时ptr指向路径名的最后,此时把文件名复制过去,相当于把文件名加到路径最后了                 
        find(fullpath);                   //递归调用find函数
    }
//  ptr[-1] = 0;这个语句,是我参考APUE上的4-7例子时写上的,仔细想想,这在这个例子中是没有用的,因为每循环完一个目录后,才会执行这条语句,但是此时的ptr不会再被用到,所以在把ptr指向的文件名连同文件名前面的斜杠(/)删除是没有意义的。
    closedir(dp);
}
运行结果:

与预期结果一样。源码如下:

#include    <sys/types.h>
#include    <sys/stat.h>
#include    <dirent.h>
#include    "ourhdr.h"


void func(char *);


void find(char *);


int main(int argc, char **argv)
{
    if (argc != 2){      printf("argument error.\n");  return(0);}


    func(argv[1]);
    return(0);
}


static  char *fullpath;
const   int pathmax=1024;
//static  int n=0;


void func(char *pathname)
{
    fullpath = malloc(pathmax + 1);
    memset(fullpath, 0 ,pathmax+1);
    strcpy(fullpath, pathname);
    find(fullpath);
}


void find(char *fullpath)
{
    struct  stat        statbuf;
    DIR     *dp;
    struct  dirent      *dirp;
    char    *ptr;


    /* printf("fullpath:%s.\t", fullpath);*/
    if( lstat(fullpath, &statbuf) < 0)
    {   printf("stat error.\n");        return;    }
    
    if ( S_ISDIR(statbuf.st_mode) == 0){ 
        printf("the filename is %s\n", fullpath);
        return;
    }
    if ( (dp = opendir(fullpath)) == NULL)
    {   printf("opendir error.\n");        return;    }
    ptr = fullpath + strlen(fullpath);
    *ptr= '/';ptr++;
    *ptr = 0;
    while ( (dirp = readdir(dp)) != NULL)
    {
        
        if (strcmp(dirp->d_name, ".") ==0 || strcmp(dirp->d_name, "..") == 0)   continue;
        strcpy(ptr, dirp->d_name);
        find(fullpath);
    }
   // printf("%3d\tfullpath:%s\t\tptr:%s\t\n", n, fullpath, ptr);
   // ptr[-1] = 0;
   // printf("%3d\tfullpath:%s\t\tptr:%s\t\n", n, fullpath, ptr);
   // n++;
    closedir(dp);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值