C 递归地列出目录

C 递归地列出目录,c,recursion,directory,directory-listing,C,Recursion,Directory,Directory Listing,我无法正确编写此函数。它应该递归地列出第一个参数(如ls-R)提供的路径中的内容,但是它停止得太快了。以下是代码、预期输出和我得到的输出: int browseDir (const char *path, const int *options) { char callingdir[MAXDIRLEN]; char currentdir[MAXDIRLEN]; getcwd(callingdir,MAXDIRLEN); DIR *dirstream; s

我无法正确编写此函数。它应该递归地列出第一个参数(如ls-R)提供的路径中的内容,但是它停止得太快了。以下是代码、预期输出和我得到的输出:

int browseDir (const char *path, const int *options)
{
    char callingdir[MAXDIRLEN];
    char currentdir[MAXDIRLEN];

    getcwd(callingdir,MAXDIRLEN);

    DIR *dirstream;
    struct dirent *dir_entry; 
    struct stat file_data;
    LIST subd_list = newList();

    if (path == NULL)
        strcpy(currentdir,callingdir);
    else
        strcpy(currentdir,path);

    dirstream = opendir(currentdir);
    printf("Listing: %s\n",currentdir);
    chdir(currentdir);

    if (dirstream == NULL)
    {
        perror("Error: cannot open directory\n");
        return 0;
    }

    while((dir_entry = readdir(dirstream)) != NULL)
    {
        if (!ISSET_A_FLAG(*options))
        {
            if (dir_entry->d_name[0]=='.')
                continue;
        }
        if (!ISSET_S_FLAG(*options))
        {
            stat(dir_entry->d_name, &file_data);
            printStat(&file_data);
        }
        printf("%s ",dir_entry->d_name);
        printf("\n");
        if (ISSET_R_FLAG(*options) && (dir_entry->d_type & DT_DIR) && strcmp(dir_entry->d_name,".") && strcmp(dir_entry->d_name,".."))
            addNode(subd_list, dir_entry->d_name);
    }
    closedir(dirstream);

    while(!isEmpty(subd_list))
    {
        browseDir((*subd_list)->data, options);
        delNode(subd_list);
    }

    chdir(callingdir);
    return 0;  
}
使用ls-Rli的输出(预期)

运行我的shell的当前输出:

> list /home/tod/programming/shelldeb -r
Listing: /home/tod/programming/shelldeb
1057517 -rw-rw-r--  1 1000 1000      244 list.h 
1054396 -rw-rw-r--  1 1000 1000     7696 commands.c 
1057590 -rw-rw-r--  1 1000 1000     1213 parsing.c 
1150597 drwxr-xr-x  3 1000 1000     4096 bin 
1045208 -rw-rw-r--  1 1000 1000      952 list.c 
1055154 -rw-rw-r--  1 1000 1000     1368 shelldeb.cbp 
1150595 drwxr-xr-x  3 1000 1000     4096 obj 
1045205 -rw-rw-r--  1 1000 1000     1233 commands.h 
1057688 -rw-rw-r--  1 1000 1000      665 shelldeb.depend 
1057721 -rw-rw-r--  1 1000 1000     1413 shelldeb.layout 
1057622 -rw-rw-r--  1 1000 1000      193 parsing.h 
1055205 -rw-r--r--  1 1000 1000      487 main.c 
Listing: obj
1150596 drwxr-xr-x  3 1000 1000     4096 Debug 
Listing: Debug
1046232 -rw-rw-r--  1 1000 1000        0 comment.txt 
1150683 drwxrwxr-x  2 1000 1000     4096 tmpfolder 
1046334 -rw-rw-r--  1 1000 1000    15088 commands.o 
Listing: tmpfolder
1054413 -rw-rw-r--  1 1000 1000        0 tmp.txt 

如果您想要一个类似于
ls
(以目录路径作为唯一参数)的程序,那么我认为您将其复杂化了,以下是我的版本:

struct dirent *file = NULL;
DIR * direc = NULL;

if((direc = opendir(argv[1])) == NULL)
{
         perror("");
         exit(-1);
}
while((file = readdir(direc)) != NULL)
        printf("%s" , file->d_name);

这里有一个基本的工作
ls
类程序

如果你想要一个
ls
类程序(它将目录路径作为唯一参数),那么我认为你把它复杂化了,下面是我的版本:

struct dirent *file = NULL;
DIR * direc = NULL;

if((direc = opendir(argv[1])) == NULL)
{
         perror("");
         exit(-1);
}
while((file = readdir(direc)) != NULL)
        printf("%s" , file->d_name);

这是一个基本的类似于ls的程序

我终于用一种非常简单的方法编写了一个递归列表函数。我在c标准库中找到了函数nftw(),基本上它完成了所有的工作。 以下是感兴趣人员的代码:

static int list (const char *path) 
{
  char calling_dir[MAXDIRLEN];
  DIR *dirstream;
  struct dirent *dir_entry; 
  struct stat file_data;

  getcwd(calling_dir,MAXDIRLEN);  
  dirstream=opendir(path);

  if (dirstream == NULL)
    {
      perror("Error: cannot open directory\n");
      return -1;
    }
  chdir(path);

  while((dir_entry = readdir(dirstream)) != NULL)
    {
      if (!ISSET_A_FLAG(options))
    {
      if (dir_entry->d_name[0]=='.')
        continue;
    }
      if (!ISSET_S_FLAG(options))
    {
      stat(dir_entry->d_name, &file_data);
      printStat(&file_data);
    }
      printf("%s ",dir_entry->d_name);
      printf("\n");
    }
  closedir(dirstream);
  chdir(calling_dir);
  return 0; 
}

static int list_R (const char *entry_path, const struct stat *entry_stat,int typeflag,struct FTW *ftwbuf)
{
  int status;
  if(typeflag & FTW_D)
    {
      printf("\nContent of %s : \n",entry_path);
      status=list(entry_path);
    }
  if (status == -1)
    return status;
  return 0;
}
使用这两个函数,您只需实现printstat(),它在目录条目上打印信息。
对nftw(路径、列表、1、ftw标志)的简单调用;设置FTW_PHYS flag后,就完成了这项工作。

我终于以一种非常简单的方式编写了一个递归列表函数。我在c标准库中找到了函数nftw(),基本上它完成了所有的工作。 以下是感兴趣人员的代码:

static int list (const char *path) 
{
  char calling_dir[MAXDIRLEN];
  DIR *dirstream;
  struct dirent *dir_entry; 
  struct stat file_data;

  getcwd(calling_dir,MAXDIRLEN);  
  dirstream=opendir(path);

  if (dirstream == NULL)
    {
      perror("Error: cannot open directory\n");
      return -1;
    }
  chdir(path);

  while((dir_entry = readdir(dirstream)) != NULL)
    {
      if (!ISSET_A_FLAG(options))
    {
      if (dir_entry->d_name[0]=='.')
        continue;
    }
      if (!ISSET_S_FLAG(options))
    {
      stat(dir_entry->d_name, &file_data);
      printStat(&file_data);
    }
      printf("%s ",dir_entry->d_name);
      printf("\n");
    }
  closedir(dirstream);
  chdir(calling_dir);
  return 0; 
}

static int list_R (const char *entry_path, const struct stat *entry_stat,int typeflag,struct FTW *ftwbuf)
{
  int status;
  if(typeflag & FTW_D)
    {
      printf("\nContent of %s : \n",entry_path);
      status=list(entry_path);
    }
  if (status == -1)
    return status;
  return 0;
}
使用这两个函数,您只需实现printstat(),它在目录条目上打印信息。
对nftw(路径、列表、1、ftw标志)的简单调用;设置FTW_PHYS标志后,将执行此操作。

欢迎使用堆栈溢出!在不知道代码是如何出错的情况下,就如何调试代码提供有用的建议要比其他方法困难得多;如果您编辑您的问题以包含您得到的输出,并详细描述它与您想要的不同之处,您将更有可能得到有用的答案。感谢您的好意,我正在使用新信息编辑代码(因为我对代码做了一点改进),我也将添加输出。尝试添加一些调试printf()例如,在递归函数的入口,在每次调用
browseDir
后,可能会列出
subd_list
,以便您可以看到它提前终止的原因。欢迎使用堆栈溢出!在不知道代码是如何出错的情况下,就如何调试代码提供有用的建议要比其他方法困难得多;如果您编辑您的问题以包含您得到的输出,并详细描述它与您想要的不同之处,您将更有可能得到有用的答案。感谢您的好意,我正在使用新信息编辑代码(因为我对代码做了一点改进),我也将添加输出。尝试添加一些调试printf()例如,在递归函数的入口,在每次调用
browseDir
后,可能会列出
subd_list
,以便您了解它为什么会提前终止。谢谢您的回答。不幸的是,我的目标是编写一个完整的基本shell,其中包含几个特性,包括ls(在本例中称为list)命令。问题是我没有成功地实现递归列表-r,它应该作为ls-r工作。谢谢你的回答。不幸的是,我的目标是编写一个完整的基本shell,其中包含几个特性,包括ls(在本例中称为list)命令。问题只是我没有成功地实现递归清单list-r,它应该与ls-r一样工作。