【问题标题】:Printing all files and folders in a path in Linux, recursively, in C [duplicate]在Linux中以递归方式在C中打印路径中的所有文件和文件夹[重复]
【发布时间】:2015-06-06 17:47:18
【问题描述】:

我一直在尝试学习如何使用函数与系统上的路径进行交互,但我想我一开始就卡住了。

我特别搜索了 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;
}

我做错了什么?

【问题讨论】:

  • current 被分配了c,然后你将它传递给下一个listdir() 调用。递归时可能需要将curr_entcurrent 结合起来。
  • 请不要重蹈覆辙。请改用nftw()。它设计就是为了做到这一点——遍历文件树。

标签: c recursion directory-listing


【解决方案1】:

它工作正常,只是忘记豁免...。这两个“虚拟”目录存在于所有目录中。 . 是“self”的快捷方式,..parent 的快捷方式。

例如如果您执行了listdir('.'),那么您将继续循环,因为您在. 中执行opendir 时首先会得到另一个.,它指向完全相同的位置。

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

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

【讨论】:

  • 你知道我怎么能忽略“。”和“..”?
【解决方案2】:

我做错了什么?

  1. 您尚未添加代码以忽略 ...
  2. 您在递归调用中使用相同的DIR*

这就是我将如何改变你的功能。

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);
}

【讨论】:

  • 第二个没看懂。我确实做到了,但是有没有办法使用“新”的?还是真的有新的?
  • 对于要遍历的每个子目录,您必须使用opendir()closedir()
  • @user3163379,查看更新后的答案。
猜你喜欢
  • 1970-01-01
  • 2015-12-21
  • 2021-10-19
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2021-09-19
  • 2013-12-27
  • 2023-03-08
相关资源
最近更新 更多