With C++17 this is also easily possible without boost. I tested the below example with VS2019.
Please see the example below. Reading the complete file list is just a very short one-liner:
std::vector fileList (fs::directory_iterator(startPath), {});
Usage of range constructor for std::vector
.
We can define the std::vector without template argument. The compiler can deduce the argument from the given function parameters. This feature is called CTAD ("class template argument deduction").
Additionally, you can see that I do not use the "end()"-iterator explicitely.
This iterator will be constructed from the empty brace-enclosed initializer list with the correct type, because it will be deduced to be the same as the type of the first argument due to the std::vector constructor requiring that.
Of course you could also check sub directories with the fs::recursive_directory_iterator
Finding the extension is then quite simple. You can of course check additional file/path attributes as well. No problem.
Please see a complete working example:
#include <iostream>
#include <filesystem>
#include <vector>
#include <iterator>
namespace fs = std::filesystem;
int main() {
// The start path
const fs::path startPath{ "C:\\temp\\" };
// And the extension to look for
const std::string extension{ ".txt" };
// Get all directory entries into our fileList vector
std::vector fileList (fs::directory_iterator(startPath), {});
// Evaluate. Go through all directory entries
for (const fs::directory_entry& de : fileList) {
// Get path as string
std::string p{ de.path().string() };
// Check if it ends with the given extension
if (p.substr(p.size() - extension.size(), extension.size()) == extension)
std::cout << p << "\n";
}
return 0;
}
Additional solution using std::transform
and std::copy_if
:
#include <iostream>
#include <filesystem>
#include <vector>
#include <iterator>
namespace fs = std::filesystem;
int main() {
// The start path
const fs::path startPath{ "C:\\temp\\" };
// And the extension to look for
const std::string extension{ ".txt" };
std::vector<std::string> files{};
// Get all path names as string
std::transform(fs::directory_iterator(startPath), {}, std::back_inserter(files), [](const fs::directory_entry & de) { return de.path().string(); });
// Output all files with extension
std::copy_if(files.begin(), files.end(), std::ostream_iterator<std::string>(std::cout,"\n"), [&extension](const std::string & p) {
return (p.substr(p.size() - extension.size(), extension.size()) == extension); });
return 0;
}