【问题标题】:How do i get a list of all files with a specific extension with c++ without <dirent.h> on windows [duplicate]如何在 Windows 上获取具有特定扩展名的所有文件的列表,而不使用 <dirent.h> [重复]
【发布时间】:2020-04-15 07:48:07
【问题描述】:

如何在 Windows 上使用不带 的 c++ 获取具有特定扩展名的所有文件的列表。 dirent.h 不适用于 Visual Studio 2019,有没有其他方法可以获取目录中所有文件的列表。

例如列表将是

file.txt
secode.txt
hello.txt
h.txt

如果没有,那么我可以让 dirent.h 在 Visual Studio 2019 中工作。

【问题讨论】:

标签: c++ windows


【解决方案1】:

如果你有 boost,你可以使用 boost::filesystem 这是一个以 jpg 扩展名获取所有图像的示例。

#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include <vector>
#include <string>
using namespace boost::filesystem;
using std::string;
using std::vector;
    void GetAllImageFromDir(path& dir, vector<path>& all_dir_images)
{
    string str(".jpg");             // store paths,
    vector<path> all_dir_files;

    std::copy(directory_iterator(dir), directory_iterator(), back_inserter(all_dir_files));

    for (int k = 0; k < all_dir_files.size(); ++k )
    {

        if (all_dir_files[k].filename_is_dot() || all_dir_files[k].filename_is_dot_dot() || !is_regular_file(all_dir_files[k]))
        {
            continue;
        }
        else
        {
            if (is_regular_file(all_dir_files[k]))
            {
                string extension = boost::filesystem::extension(all_dir_files[k].string());

                    if (extension.compare(str) == 0)
                    {
                        all_dir_images.push_back(all_dir_files[k]);
                    }
            }
        }
    }
}

【讨论】:

  • 你能把你在代码中使用的所有库都显示出来吗
  • 我用我记得的内容进行编辑,如果不编译,我会检查缺少的内容
  • 无法打开源文件“boost/filesystem.hpp” 无法打开源代码“boost/filesystem/path.hpp”
  • 你需要构建 boost 并将其添加到以前的编译中 boost.org/doc/libs/1_65_1/more/getting_started/…
【解决方案2】:

使用 C++17,这也很容易实现,无需增强。我用 VS2019 测试了下面的例子。

请看下面的例子。阅读完整的文件列表只是很短的一句话:

std::vector fileList (fs::directory_iterator(startPath), {});

std::vector 的范围构造函数的使用。

我们可以在没有模板参数的情况下定义 std::vector。编译器可以从给定的函数参数中推断出参数。此功能称为 CTAD(“类模板参数推导”)。

此外,您可以看到我没有明确使用“end()”-iterator。

这个迭代器将从带有正确类型的空大括号括起来的初始值设定项列表中构造出来,因为 std::vector 构造函数要求它与第一个参数的类型相同。

当然你也可以用fs::recursive_directory_iterator检查子目录

然后查找扩展非常简单。您当然也可以检查其他文件/路径属性。没问题。

请查看完整的工作示例:

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

使用std::transformstd::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;
}

【讨论】:

    猜你喜欢
    • 2019-06-14
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多