【问题标题】:Unix c program to list directories recursivelyUnix c程序以递归方式列出目录
【发布时间】:2011-08-12 04:55:18
【问题描述】:

我正在进行一项 POSIX C 学习练习,该练习涉及递归地列出指定目录中的文件/文件夹。该程序接受一个或多个目录的参数。我可以很好地列出初始目录的内容,但递归有问题。我为递归函数调用传递参数的方式有问题吗?

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>

void listdir(char *argv[])
{
  DIR *mydirhandle;

  struct dirent *mydirent;

  struct stat statinfo;

  int n = 1;

  while(argv[n] != NULL)
  {
    if((mydirhandle = opendir(argv[n])) == NULL)
    {
      perror("opendir");
      exit(1);
    }

    printf("%s/\n", argv[n]);

    while((mydirent = readdir(mydirhandle)) != NULL)
    { 
      if((strcmp(mydirent->d_name, ".") == 0) || (strcmp(mydirent->d_name, "..") == 0))

      {
        continue;
      }

      else           
      {
        printf("\t%s\n", mydirent->d_name);

         //check if next entry is a directory       
         if(mydirent->d_type == DT_DIR)
        {   
             //is current directory being passed correctly here?
            listdir(mydirent->d_name);
        }
      }        
    }                       
    n++;
    closedir(mydirhandle);
  }
}
int main(int argc, char *argv[])
{
  if(argc < 2)
  {
    printf("usage: %s <directory>\n", argv[0]);
    return 0;
  }

  listdir(argv);
  return 0;
}

【问题讨论】:

    标签: c unix posix


    【解决方案1】:

    struct dirent 的 d_name 成员是相关项目的基本名称。所以,如果你正在浏览这样的目录:

    .
    ..
    where-is/
       pancakes/
           .
           ..
           house
    

    一旦您进入where-is,您将尝试listdir("pancakes"),但这不起作用,因为您需要listdir("where-is/pancakes")。

    您需要将其与您正在查找的目录的名称结合起来,然后才能将某些内容传递给下一个 listdir 调用。

    你会想要替换这样的东西:

    listdir(mydirent->d_name);
    

    这样的事情:

    char *next_dir = malloc(strlen(argv[n]) + strlen(mydirent->d_name) + 1 + 1);
    sprintf(next_dir, "%s/%s", argv[n], mydirent->d_name);
    listdir(next_dir);
    free(next_dir);
    

    或者,您可以在输入目录时chdir 进入目录,然后在完成后将chdir 备份。

    【讨论】:

      【解决方案2】:

      打开警告将表明您在进行递归函数调用时传递了错误的类型。我会简单地让listdir 使用char * 参数而不是char **,然后在需要时在main 中使用for 循环来循环多个参数。

      【讨论】:

        【解决方案3】:

        您应该为此使用ftw,它会在子树的每个项目上调用给定的回调。这样,您可以避免自己使用显式递归,并且您的代码会变得更短。

        【讨论】:

          猜你喜欢
          • 2015-05-06
          • 1970-01-01
          • 1970-01-01
          • 2013-08-17
          • 2013-07-01
          • 2013-10-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多