在C中以递归方式打印Linux中路径中的所有文件和文件夹

时间:2015-04-01 22:04:02

标签: c recursion directory-listing

我一直在努力学习如何使用函数与系统中的路径进行交互,但我想我一开始就坚持了。

我特别搜索了web和stackoverflow,找不到像我想做的那样的基本实现。还有一些其他问题,与我的相似,但我发现它们并不像我的那样简单和初学者友好。

这是代码,这段代码只打印给定路径中的文件,“。”和“..”

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

void listdir(DIR *c);

int main()
{

    DIR* root_d;
    root_d = opendir("/home/foo/Desktop/testx");
    listdir(root_d);

}

void listdir(DIR *c){
    DIR* current = c;
    struct dirent *curr_ent;
    if((curr_ent =readdir(current)) != NULL && curr_ent->d_type == DT_DIR){
        listdir(current);
    }
    printf("%s\n", curr_ent->d_name);
    return;
}

我做错了什么?

2 个答案:

答案 0 :(得分:3)

它完全正常工作,你只是忘了免除...。那两个&#34;虚拟&#34;目录存在于所有目录中。 .是&#34; self&#34;的快捷方式,..parent的快捷方式。

e.g。如果您执行了listdir('.'),那么您只需继续循环,因为您在opendir中执行.的第一件事就是另一个.,它指向完全相同的地方。

简而言之,您需要以下伪代码:

if (dir != '.' && dir != '..' && is_dir(dir)) {
    listdir(dir);
}

答案 1 :(得分:1)

  

我做错了什么?

  1. 您尚未添加代码以忽略...
  2. 您在递归调用中使用相同的DIR*
  3. 以下是我改变你的功能的方法。

    int is_dot_or_dot_dot(char const* name)
    {
       return (strcmp(name, ".") == 0 || strcmp(name, "..") == 0 );
    }
    
    void listdir(char const* dirname)
    {
       char* subdir;
       DIR* dirp = opendir(dirname);
       struct dirent *curr_ent;
    
       if ( dirp == NULL )
       {
          return;
       }
    
       while ( (curr_ent = readdir(dirp)) != NULL )
       { 
          // Print the name.
          printf("%s\n", curr_ent->d_name);
    
          // Traverse sub-directories excluding . and ..
          // Ignore . and ..
          if ( curr_ent->d_type == DT_DIR && ! (is_dot_or_dot_dot(curr_ent->d_name)) )
          {
             // Allocate memory for the subdirectory.
             // 1 additional for the '/' and the second additional for '\0'.
             subdir = malloc(strlen(dirname) + strlen(curr_ent->d_name) + 2);
    
             // Flesh out the subdirectory name.
             strcpy(subdir, dirname);
             strcat(subdir, "/");
             strcat(subdir, curr_ent->d_name);
    
             // List the contents of the subdirectory.
             listdir(subdir);
    
             // Free the allocated memory.
             free(subdir);
          }
       }
    
       // Close the directory
       closedir(dirp);
    }