【问题标题】:Recursive directory reading递归目录读取
【发布时间】:2013-04-01 21:48:38
【问题描述】:

我正在尝试递归获取目录的所有文件和子文件夹。这是我目前所拥有的。

#include <iostream>
#include "dirent.h"
#include <io.h>

using namespace std;

void listDir(char *directory)
{
    DIR *dir;
    struct dirent *ent;
    if((dir = opendir (directory)) != NULL)
    {
        while ((ent = readdir (dir)) != NULL)
        {
            if(strstr(ent->d_name,".") != NULL)
                cout<<ent->d_name<<endl;
            else
            {
                strcat(directory,ent->d_name);
                strcat(directory,"\\");
                strcat(directory,"\0");
                cout<<directory<<endl;
                cin.get();
                listDir(directory);
            }
        }
    }
    closedir (dir);
}

int main(int param, char **args)
{
    char *path = new char[];
    path = args[1];
    strcat(path, "\\");
    listDir(path);
    cin.get();
    return 0;
}

我正在使用 dirent(实际上很酷,如果您还没有的话,请获取它)并且当我递归获取文件夹时,它似乎添加到我的子文件夹末尾的目录中。例如:

Downloads、Images 和 Includes 都是我的 Jakes625 文件夹的子文件夹。也许我错过了什么?

【问题讨论】:

  • 你有什么问题?
  • 这段代码甚至无法编译:这条语句需要一个大小:char *path = new char[];你为什么不使用 c++ 字符串?
  • 为什么这个标签是 C 而不是 C++?您使用的是#include &lt;iostream&gt;,所以它必须是 C++,而不是 C。
  • 您的问题是什么?您想要程序做什么而不是它现在做什么?
  • 递归列出每个子目录中的每个文件。

标签: c++ recursion


【解决方案1】:
#include <unistd.h>
#include <dirent.h>

#include <iostream>

using namespace std;

void listDir(const string& path)
{
  DIR *dir;
  struct dirent *ent;

  if((dir = opendir (path.c_str())) != NULL)
  {
    while ((ent = readdir (dir)) != NULL)
    {
      if(string(ent->d_name).compare(".") != 0)
      {
        cout<< ent->d_name << endl;
      }
      else
      {
        string nextDir = string(ent -> d_name);
        nextDir += "\\";

        cout <<  nextDir << endl;

        listDir(nextDir);
      }
    }
  }

  closedir (dir);
}

int main(int param, char **args)
{
  string path = string(args[1]);
  listDir(path);

  return 0;
}

我重写了它,使它使用 c++ 字符串:这里没有理由使用 C 字符串。现在可以了。有一些小问题,但最重要的是您在分配 char 数组时没有指定大小。这行是罪魁祸首:

char *path = new char[]; // bad!

如果您不指定大小,则分配器不知道要从堆中请求多少字节。您的程序不需要堆分配,因为没有数据需要超过其封闭词法块的情况。

【讨论】:

  • 顺便说一句,这段代码还有很多问题,缺少很多必需的错误检查。
  • 在某些平台上您可能还需要#include &lt;string&gt;
【解决方案2】:

https://en.cppreference.com/w/cpp/filesystem/recursive_directory_iterator

    for(auto& p: fs::recursive_directory_iterator("my_directory"))
        std::cout << p.path() << '\n';

这是一个例子

#include <fstream>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
 
int main()
{
    fs::current_path(fs::temp_directory_path());
    fs::create_directories("sandbox/a/b");
    std::ofstream("sandbox/file1.txt");
    fs::create_symlink("a", "sandbox/syma");
    for(auto& p: fs::recursive_directory_iterator("sandbox"))
        std::cout << p.path() << '\n';
    fs::remove_all("sandbox");
}

输出:

"sandbox/a"
"sandbox/a/b"
"sandbox/file1.txt"
"sandbox/syma"

【讨论】:

    猜你喜欢
    • 2011-09-30
    • 2018-08-12
    • 2011-09-27
    • 2018-03-05
    • 2022-12-30
    • 2021-01-29
    • 2015-07-13
    • 1970-01-01
    • 2020-03-13
    相关资源
    最近更新 更多