c++ - C++中的递归列表文件不会进入所有子目录

标签 c++ linux list file directory

!!!解决了!!!

谢谢大家的帮助,现在一切正常。我按照@RSahu 的建议更改了我的代码并使其正常工作。
感谢您的所有意见,我一直坚持这个。
致@Basile:我一定会检查一下,但是对于这段特定的代码,我不会使用它,因为它看起来太复杂了:)但是感谢您的建议。



原始问题

我正在尝试制作一个 C++ 代码来列出给定目录及其子目录中的所有文件。

快速解释

想法是函数 list_dirs(_dir, _files, _current_dir) 将从顶层目录开始并将文件放入 vector _files 中,当它找到一个目录时它会调用自己在这个目录上。如果在子目录中,_current_dir 将被添加到文件名之前,因为我需要知道路径结构(它应该生成 sitemap.xml)。
list_dirs 中有一个对 list_dir 的调用,它只返回当前目录中的所有文件,不区分文件和目录。

我的问题

代码现在做的是列出原始目录中的所有文件,然后列出一个子目录中的所有文件,但跳过所有其他子目录。它会列出它们,但不会列出其中的文件。
更神秘的是,它只列出了这个特定目录中的文件,没有其他目录。我尝试在多个位置运行它,但它从未进入任何其他目录。

提前致谢,请注意我是 C++ 的初学者,所以请不要苛刻 ;)
列表目录

int list_dir(const std::string& dir, std::vector<std::string>& files){
    DIR *dp;
    struct dirent *dirp;
    unsigned fileCount = 0;

    if ((dp = opendir(dir.c_str())) == NULL){
        std::cout << "Error opening dir." << std::endl;
    }

    while ((dirp = readdir(dp)) != NULL){
        files.push_back(std::string (dirp->d_name));
        fileCount++;
    }

    closedir(dp);
    return fileCount;
}

和 LIST_DIRS

int list_dirs (const std::string& _dir, std::vector<std::string>& _files, std::string _current_dir){
    std::vector<std::string> __files_or_dirs;

    list_dir(_dir, __files_or_dirs);

    std::vector<std::string>::iterator it = __files_or_dirs.begin();
    struct stat sb;

    while (it != __files_or_dirs.end()){
        if (lstat((&*it)->c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){
            /* how to do this better? */
            if (*it == "." || *it == ".."){
                __files_or_dirs.erase(it);
                continue;
            }

            /* here it should go into sub-directory */
            list_dirs(_dir + *it, _files, _current_dir + *it);

            __files_or_dirs.erase(it);
        } else {
            if (_current_dir.empty()){
                _files.push_back(*it);
            } else {
                _files.push_back(_current_dir + "/" + *it);
            }
            ++it;
        }
    }
}

最佳答案

主要问题在行中:

if (lstat((&*it)->c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){

您在调用 lstat 时使用了目录条目的名称。当函数处理子目录时,条目名称不代表有效路径。你需要使用类似的东西:

std::string entry = *it;
std::string full_path = _dir + "/" + entry;
if (lstat(full_path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){

改进建议

更新 list_dir,使其在输出中不包含 "."".."。从一开始就排除这些文件对我来说很有意义。

int list_dir(const std::string& dir, std::vector<std::string>& files){
   DIR *dp;
   struct dirent *dirp;
   unsigned fileCount = 0;

   if ((dp = opendir(dir.c_str())) == NULL){
      std::cout << "Error opening dir." << std::endl;
   }

   while ((dirp = readdir(dp)) != NULL){
      std::string entry = dirp->d_name;
      if ( entry == "." or entry == ".." )
      {
         continue;
      }

      files.push_back(entry);
      fileCount++;
   }

   closedir(dp);
   return fileCount;
}

list_dirs 中,不需要从 _files_or_dirs 中删除项目。可以使用 for 循环并通过删除从 _files_or_dirs 中删除项目的调用来简化代码。

我不清楚 _current_dir 的用途是什么。也许它可以被删除。

这是该函数的更新版本。 _current_dir 仅用于构造递归调用中参数的值。

int list_dirs (const std::string& _dir,
               std::vector<std::string>& _files, std::string _current_dir){
   std::vector<std::string> __files_or_dirs;

   list_dir(_dir, __files_or_dirs);

   std::vector<std::string>::iterator it = __files_or_dirs.begin();
   struct stat sb;

   for (; it != __files_or_dirs.end() ; ++it){
      std::string entry = *it;
      std::string full_path = _dir + "/" + entry;

      if (lstat(full_path.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)){
         /* how to do this better? */

         /* here it should go into sub-directory */
         list_dirs(full_path, _files, _current_dir + "/" + entry);

      } else {
         _files.push_back(full_path);
      }
   }
}

关于c++ - C++中的递归列表文件不会进入所有子目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34260221/

相关文章:

c++ - 具有折叠表达式的模板会创建不需要的参数拷贝

c++ - 如何使用 freeglut 创建一个显示 glpoints 的窗口?

c++ - 如何使用指针和引用 C++ 和 VALGRIND?

c - 添加两个宏并在预处理阶段转换为字符串

linux - "clock skew detected” 安装时出现警告

linux - 如何使用 bluez 在 Linux 上通过蓝牙 4.0 LE 连接到 FitBit Zip?

Python 连接列表

c++ - 如何从 #define 中删除 C 风格的转换,以便我可以在预处理器 #if 中使用它?

list - Flutter 水平 ListView 点指示器

python - Python 中的元组到底是什么?