10

現在のフォルダーとそのすべてのサブフォルダーにあるすべてのファイルのリストを返す関数を作成しようとしています。私はこのコードを書きました:

#include <iostream>
#include <dirent.h>
#include <cstring>

using namespace std;

int main() {
   DIR* dir; dirent* pdir;
   //From my workspace
   dir=opendir(".");     
   while (pdir=readdir(dir)) {
       if(/**********This pdir is a directory**********/) {
           /**********RECURSIVE CALL SHOULD BE HERE**********/
           cout<<pdir->d_name<<endl;
       }
   }
   closedir(dir);
   return 0;
}

私はグーグルでそれを検索しました、そして私は方法がわかりません:

  • 現在pdirがディレクトリかどうかを確認します
  • ディレクトリ内に移動し、ディレクトリに対して再帰呼び出しを実行します

その間、再帰関数がどの引数を持つべきかまだわからないので、私はすべてをメインにしています。

ヒントはありますか?

4

9 に答える 9

12

提案された標準ファイルシステムライブラリを使用したバージョンは次のとおりです。

#include <iostream>
#include <filesystem>

using namespace std;
using namespace std::tr2::sys;

void main()
{   
  for (recursive_directory_iterator i("."), end; i != end; ++i) 
    if (!is_directory(i->path()))
      cout << i->path().filename() << "\n";
} 
于 2014-05-14T15:17:09.693 に答える
8

再帰関数の記述方法を学ぶことが目標でない限り、 Boost.Filesystemに基づくこの単純なループを好むかもしれません。

#include "boost/filesystem.hpp"
#include <iostream>

int main () {
  for ( boost::filesystem::recursive_directory_iterator end, dir("./");
    dir != end; ++dir ) {
    // std::cout << *dir << "\n";  // full path
    std::cout << dir->path().filename() << "\n"; // just last bit
  }
}

または、単一の関数呼び出しですら:

std::copy(
  boost::filesystem::recursive_directory_iterator("./"),
  boost::filesystem::recursive_directory_iterator(),
  std::ostream_iterator<boost::filesystem::directory_entry>(std::cout, "\n"));
于 2012-10-29T21:44:11.893 に答える
8

C ++ 11での私のアプローチ:

#include <string>
#include <functional>
#include <dirent.h>

void listFiles(const std::string &path, std::function<void(const std::string &)> cb) {
    if (auto dir = opendir(path.c_str())) {
        while (auto f = readdir(dir)) {
            if (!f->d_name || f->d_name[0] == '.') continue;
            if (f->d_type == DT_DIR) 
                listFiles(path + f->d_name + "/", cb);

            if (f->d_type == DT_REG)
                cb(path + f->d_name);
        }
        closedir(dir);
    }
}

使用法:

listFiles("my_directory/", [](const std::string &path) {
    std::cout << path << std::endl;
});
于 2017-10-31T22:09:47.723 に答える
5

ベースディレクトリパスをパラメータとして取るプロシージャでそのコードを分離し、実際に再帰呼び出しを実行できるようにします。それは次のようなものでなければなりません

void recursive_file_list(const char * directory)
{
    // ...
}

次に、pdir取得したディレクトリがディレクトリであるかどうかを確認するには、次の2つのルートがあります。

  • 次の場合に確認できpdir->d_type==DT_DIRます; これにより、この情報がすぐに得られますが、移植性はありません(POSIXはd_typeメンバーの存在を義務付けていません)。また、すべてのファイルシステムでサポートされているわけではないため、を取得する可能性がありますDT_UNKNOWN。シンボリックリンクをたどりたい場合は、を取得した場合にも追加のチェックを実行する必要がありますDT_LNK。このような場合は、フォールバックする必要がありますlstat(以下のポイントを参照)。
  • 代わりに、特に。のフィールドをlstatチェックして、各ファイルに関する情報を取得するために移植可能に使用できます。st_modestruct stat
于 2012-10-29T20:50:49.727 に答える
4

C ++ 17 recursive_directory_iteratorを使用すると、次のように簡潔になります。

void ls_recursive(const std::filesystem::path& path) {
    for(const auto& p: std::filesystem::recursive_directory_iterator(path)) {
        if (!std::filesystem::is_directory(p)) {
            std::cout << p.path() << '\n';
        }
    }
}

出力例:

"/home/user/prj/rust/stack/Cargo.toml"
"/home/user/prj/rust/stack/.gitignore"
"/home/user/prj/rust/stack/src/main.rs"
"/home/user/prj/rust/stack/.git/config"
于 2019-01-26T20:01:49.353 に答える
2

標準のc++機能を使用します。コードにサードパーティのライブラリを含める必要はありません。

ディレクトリパスのみをパラメータとして送信します。そのフォルダとそのサブフォルダに存在するすべてのファイルパスが元に戻ります。

さらに、特定の種類のファイル(.txtまたは.jpgなど)を並べ替える必要がある場合は、拡張子を渡すと、それぞれの拡張子を持つすべてのファイルパスが出力されます。

#include <Windows.h>
#include<iostream>
#include<vector>
#include<string>
using namespace std;

vector<string> files;

std::string Recursive(std::string folder) {
    std::string search_path = folder + "/*.*";
    WIN32_FIND_DATA fd;
    HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
    std::string tmp;
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                if (!(!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, ".."))) {
                    tmp = folder + "\\";
                    tmp = tmp + fd.cFileName;
                    Recursive(tmp);
                }
            }
            else {
                std::string FinalFilePath = folder + "\\" + fd.cFileName;
                files.push_back(FinalFilePath);
            }

        } while (::FindNextFile(hFind, &fd));
        ::FindClose(hFind);
    }
    return folder;
}

bool has_suffix(const std::string& str, const std::string& suffix) {
    return str.size() >= suffix.size() &&
        str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

int main(){
std::string folder = "C:\\Users\\Omkar\\Desktop\\Test";
    Recursive(folder);
    std::string t;
    const auto needle = std::string(".txt");
    while (!files.empty()) {
        t = files.back();
        if (has_suffix(t, ".mmt")) {
            cout << "FINAL PATH : " << t << endl;
            t.clear();
        }
        files.pop_back();
    }
return 0;
}
于 2021-10-13T11:09:42.190 に答える
1

パスはのようになります /your_path/。非表示のフォルダ内を検索するには、3番目のパラメータを追加する必要がありますtrue

#include <dirent.h>
#include <vector>
#include <cstring>    

void GetReqDirs(const std::string& path, std::vector<string>& files,const bool showHiddenDirs = false){
    DIR *dpdf;
    struct dirent *epdf;
    dpdf = opendir(path.c_str());
    if (dpdf != NULL){
        while ((epdf = readdir(dpdf)) != NULL){
            if(showHiddenDirs ? (epdf->d_type==DT_DIR && string(epdf->d_name) != ".." && string(epdf->d_name) != "." ) : (epdf->d_type==DT_DIR && strstr(epdf->d_name,"..") == NULL && strstr(epdf->d_name,".") == NULL ) ){
                GetReqDirs(path+epdf->d_name+"/",files, showHiddenDirs);
            }
            if(epdf->d_type==DT_REG){
                files.push_back(path+epdf->d_name);
            }
        }
    }
    closedir(dpdf);
}
于 2015-11-24T15:24:58.087 に答える
0

「。」がないか確認できます。文字列で。

if(strstr(pdir->d_name,".") != NULL)
于 2013-04-01T14:41:59.643 に答える
0

ここで私はそれをどのように使用するか

std::vector<std::string> get_all_files_recursive(const fs::path& path)
    {
        std::vector<std::string> result;

        for (const auto& p : fs::recursive_directory_iterator(path))
        {
            if (!fs::is_directory(p))
            {
                fs::path path = p.path();
                result.push_back(path.u8string());
            }
        }

        return result;
    }
于 2020-05-31T16:57:46.893 に答える