1

I'm trying to write a function that will save the names of files in a particular folder that have the extension .fac into a vector so that I can use them later. I found this in an older question How to get list of files with a specific extension in a given folder? , which seems to be exactly what I'm looking for but I clearly don't know how to use it correctly. When I try to list the elements of the vector I get nothing and checking the size of the vector shows 0. This is what I've tried:

#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;
}

I'm pretty new to using Boost libraries and still a novice in C++ so I'd appreciate any help with this. I'm using Visual Studio 2019 on Windows 10.

Allod
  • 17
  • 5
  • What do you get if you try to just list all the files in the same directory that the program is running? – Ian Gralinski Jun 17 '20 at 15:44
  • Are you sure that the current directory of the process is the folder that you are trying to search in? – Alan Birtles Jun 17 '20 at 15:45
  • @IanGralinski I can get a list of all the files in the directory, including the one .fac file I put in to test it. But to do that I used tut4.cpp, one of the example files that come with Boost – Allod Jun 17 '20 at 15:56
  • @AlanBirtles Yes I am, I have also tried putting in the full path explicitly D:\...\Debug which also didn't work – Allod Jun 17 '20 at 16:01
  • are the extensions in the correct case? Your code works for me – Alan Birtles Jun 17 '20 at 16:05
  • They are I believe, I've tried it for different extensions as well with the same result – Allod Jun 17 '20 at 16:20
  • @AlanBirtles I think I've figured it out, it was entirely my own stupidity and a quirk of VS. When using Debug to test it the vector is always empty but when opening the .exe directly it does indeed work. Thank you for the help – Allod Jun 17 '20 at 16:33

1 Answers1

0

@AlanBirtles I think I've figured it out, it was entirely my own stupidity and a quirk of VS. When using Debug to test it the vector is always empty but when opening the .exe directly it does indeed work. Thank you for the help

Without a doubt this is down to the current working directory.

When debugging the current working directory is chosen by Visual Studio based on the project folder and debug-configuration. I think it's usually the output folder containing the binary being debugged, unless you override it.

What you probably want to do in your program, instead is avoid relying on the current working directory - unless of course you're designing a "interactive" CLI utility (think, like ls) that is supposed to be "contextual" to the current directory.

BONUS

Since that older answer a lot has changed. Here's a version with std::filesystem, ranges v3 and fmt instead of 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());
    }
}

When executed with e.g. ./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"

As you can see I planted some dummy .fac files in random locations to test this.

Note also that I return path(), not path().filename() because otherwise you lose the location information.


sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thank you very much for the alternative, indeed I didn't have any idea of how Visual Studio chooses the Debugging directory, it's good to know for the future. I was inclined to use the current directory just for the sake of simplicity while testing different aspects of the program. It was easier having just the one place to gather all the necessary files but later I will spread them out to dedicated folders to keeps things tidy. – Allod Jun 19 '20 at 13:21