Сохранение имен файлов с указанным расширением c в конкретной папке с Boost Filesystem C ++ - PullRequest
1 голос
/ 17 июня 2020

Я пытаюсь написать функцию, которая сохранит имена файлов в определенной папке с расширением .fa c в вектор, чтобы я мог использовать их позже. Я нашел это в более старом вопросе Как получить список файлов с определенным расширением c в данной папке? , что, кажется, именно то, что я ищу, но я явно не знаю как правильно им пользоваться. Когда я пытаюсь перечислить элементы вектора, я ничего не получаю, а проверка размера вектора показывает 0. Вот что я пробовал:

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

using namespace std;
namespace fs = ::boost::filesystem;

// return the filenames of all files that have the specified extension
// in the specified directory and all subdirectories
void get_all(const fs::path& root, const string& ext, vector<fs::path>& ret)
{
    if (!fs::exists(root) || !fs::is_directory(root)) return;
        fs::recursive_directory_iterator it(root);
        fs::recursive_directory_iterator endit;

    while (it != endit)
    {
        if (fs::is_regular_file(*it) && it->path().extension() == ext) ret.push_back(it->path().filename());
        ++it;

    }

}

int main()
{
    int i;
    vector<fs::path> file_names;

    get_all(".", ".fac", file_names); //searching for .fac files in programs home directory

    for  ( i = 0; i < file_names.size();  i++) //output list of .fac files found
    {
        cout << file_names.at(i) << "\n";
    }

    cout << file_names.size();  //checking size of vector

    return 0;
}

Я новичок в использовании библиотек Boost и все еще новичок в C ++, поэтому был бы признателен за любую помощь с этим. Я использую Visual Studio 2019 на Windows 10.

1 Ответ

0 голосов
/ 19 июня 2020

@ AlanBirtles Я думаю, что понял это, это была полностью моя собственная глупость и причуда VS. При использовании Debug для тестирования вектор всегда пуст, но при открытии .exe напрямую он действительно работает. Спасибо за помощь.

Без сомнения, это связано с текущим рабочим каталогом.

При отладке текущий рабочий каталог выбирается Visual Studio на основе папки проекта и отладки -конфигурация. Я думаю, что обычно это выходная папка, содержащая отлаживаемый двоичный файл, если вы не переопределите его.

Вместо этого вы, вероятно, хотите делать в своей программе, избегайте полагаться на текущий рабочий каталог - если, конечно, вы не разработка «интерактивной» утилиты CLI (например, ls), которая должна быть «контекстной» для текущего каталога.

БОНУС

С тех пор, как этот старый ответ сильно изменился. Вот версия с std::filesystem, ranges v3 и fmt вместо Boost:

Compiler Explorer

#include <filesystem>
#include <iostream>
#include <fmt/ranges.h>
#include <fmt/printf.h>
#include <range/v3/all.hpp>

namespace fs = std::filesystem;
using paths = std::vector<fs::path>;

namespace r = ::ranges;
namespace v = r::views;

// return the paths of all files that have the specified extension in the
// specified directory and all subdirectories
auto find_ext(const fs::path& root, const std::string& ext) {
    auto it = fs::recursive_directory_iterator(root, fs::directory_options::skip_permission_denied);
    return r::subrange(it)
        | v::transform(&fs::directory_entry::path)
        | v::filter([](auto& p) { return fs::is_regular_file(p); })
        | v::filter([=](auto& p) { return p.extension() == ext; })
        ;
}

auto find_ext(std::string ext) {
    return [=](fs::path const& root) { return find_ext(root, ext); };
}

int main(int argc, char** argv) {
    auto folders = r::subrange(argv+1, argv+argc);

    for (auto&& fac : folders | v::transform(find_ext(".fac")) | v::join) {
        fmt::print("File {} found in folder {}\n", fac.filename(), fac.parent_path());
    }
}

При выполнении, например, с ./test.exe . /tmp:

File "dummy.fac" found in folder "./.git/logs/refs/heads"
File "dummy.fac" found in folder "./.git/logs/refs/remotes/gogs"
File "dummy.fac" found in folder "./.git/objects/b7"
File "dummy.fac" found in folder "./.git/objects/4b"
File "dummy.fac" found in folder "./.git/objects/63"
File "dummy.fac" found in folder "./.git/objects/36"
File "dummy.fac" found in folder "./.git/objects/af"
File "dummy.fac" found in folder "./.git/objects/17"
File "dummy.fac" found in folder "./.git/objects/7f"
File "dummy.fac" found in folder "./.git/objects/40"
File "dummy.fac" found in folder "/tmp/build-boost/boost/bin.v2/libs/timer/build/gcc-7/release/link-static"
File "dummy.fac" found in folder "/tmp/build-boost/boost/bin.v2/libs/nowide/build/gcc-7"
File "dummy.fac" found in folder "/tmp/build-boost/boost/bin.v2/libs/system/build/gcc-7/release/link-static/threading-multi"
File "dummy.fac" found in folder "/tmp/build-boost/boost/bin.v2/libs/locale/build/gcc-7/release/threadapi-pthread/threading-multi/visibility-hidden/util"
File "dummy.fac" found in folder "/tmp/.profiles/sehe/.cache/spotify/Data/1d"
File "dummy.fac" found in folder "/tmp/.profiles/sehe/.cache/spotify/Data/b1"
File "dummy.fac" found in folder "/tmp/.profiles/sehe/.cache/spotify/Storage/11"
File "dummy.fac" found in folder "/tmp/.profiles/sehe/.cache/spotify/Storage/c7"
File "dummy.fac" found in folder "/tmp/.font-unix"

Как видите, я поместил несколько фиктивных файлов .fa c в случайные места, чтобы проверить это.

Обратите внимание, что я возвращаю path(), а не path().filename(), потому что в противном случае вы потеряете информацию о местоположении.


...