c - C 中的递归目录

标签 c recursion directory

我是 C 的新手,正在尝试递归访问当前工作目录中的所有目录/文件并输出它们的信息。我遇到的问题是,我想不出一个好的解决方法是,当同一目录中有两个文件夹时,路径第二次构建错误。例如,如果在“/something/dir1”完成后 dir1 和 dir2 位于同一路径中,则路径应变为“/something/dir2”,但由于我编写内容的方式而变为“/something/dir1/dir2”。我想只跟踪以前的路径,但我不确定是否有一种方法可以做到这一点,而不会在每次递归调用时不断重写它。

更新:我已经修复了我遇到的原始错误,并想在这里发布我的新代码。我不知道的技巧是 opendir(".") 和 changedir("..") 实际上会将句点转换为完整的当前或先前路径。至于将 type = 8 和 type = 4 语句更改为更具可读性的 S_ISDIR(statbuf.st_mode) 和 S_ISREG(statbuf.st_mode) 语句,它们似乎根本不起作用,而 type 语句可以。不确定语法和我尝试使用它们的方式有什么问题。

更新 2:我在这里解决了 S_ISDIR/S_ISREG 问题 - How to use S_ISREG() and S_ISDIR() POSIX Macros?

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

void helper(DIR *, struct dirent *, struct stat, char *, int);
void dircheck(DIR *, struct dirent *, struct stat, char *, int);

int main(int argc, char *argv[]){

  DIR *dip;
  struct dirent *dit;
  struct stat statbuf;
  char currentPath[FILENAME_MAX];
  int depth = 0; /*Used to correctly space output*/

  dip = opendir(".");
  getcwd(currentPath, FILENAME_MAX);

  while((dit = readdir(dip)) != NULL){

    /*Skips . and ..*/
    if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0)
      continue;

    stat(currentPath, &statbuf);

    /*Checks if current item is of the type file (type 8)*/
    if(dit->d_type == 8)
      printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size);

    /*Checks if current item is of the type directory (type 4)*/
    if(dit->d_type == 4)
      dircheck(dip, dit, statbuf, currentPath, depth);

  }
  return 0;
}

/*Recursively called helper function*/
void helper(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth){
  int i = 0;
  dip = opendir(currentPath);

  while((dit = readdir(dip)) != NULL){

    if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0)
      continue;

    stat(currentPath, &statbuf);

    if(dit->d_type == 8){
      for(i = 0; i < depth; i++)
        printf("    ");
      printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size);
    }

    if(dit->d_type == 4)
      dircheck(dip, dit, statbuf, currentPath, depth);

  }
}

void dircheck(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth){
  int i = 0;

  strcat(currentPath, "/");
  strcat(currentPath, dit->d_name);

  /*If two directories exist at the same levelt the path
    is built wrong and needs to be corrected*/
  if((chdir(currentPath)) == -1){
    chdir("..");
    getcwd(currentPath, FILENAME_MAX);
    strcat(currentPath, "/");
    strcat(currentPath, dit->d_name);

    for(i = 0; i < depth; i++)
      printf ("    ");
    printf("%s (subdirectory)\n", dit->d_name);
    depth++;
    helper(dip, dit, statbuf, currentPath, depth);
  }

  else{
    for(i =0; i < depth; i++)
      printf("    ");
    printf("%s (subdirectory)\n", dit->d_name);
    chdir(currentPath);
    depth++;
    helper(dip, dit, statbuf, currentPath, depth);
  }

}

最佳答案

不要不必要地重新发明轮子。如果您在 unixy 系统上,nftw 库函数(POSIX 中 XSI 选项组的一部分,这意味着它几乎普遍可用)完全满足您的需求:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/nftw.html

另一方面,如果您将此作为学习练习,或者如果您有一个(相当罕见的)实例,其中 nftw 不适合您的需求(例如,如果您需要同时从多个线程执行目录递归)继续调试您的解决方案。

关于c - C 中的递归目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4915538/

相关文章:

linux - 将文件从一个文件夹投影到另一个文件夹

visual-studio-2012 - 在wix中创建文件夹

python - 使用 Python 检测 C 文件中的递归

layout - 在 Haskell 中,对于递归函数使用守卫比模式更好吗?

javascript - 如何在递归函数内完成for循环?

java - 内存游戏算法的递归函数?

c - 如何通过点击按钮在后端运行代码?在gtk+中执行此操作的函数是什么?

具有挑战性的递归问题 - 表示进程的树节点

C - Linux 上的一个简单的 shell - 命令的一些问题

c# - 在 C#.Net 中查找工作项目目录