unix系统上的C++中的简单glob?

Ben*_*ier 27 c++ unix glob

我想在以下模式中检索此模式后面的所有匹配路径vector<string>:

"/some/path/img*.png"
Run Code Online (Sandbox Code Playgroud)

我怎么能这么做呢?

Pit*_*kul 51

我有我的要点.我在glob周围创建了一个stl包装器,以便它返回string的向量并负责释放glob结果.效率不是很高但是这段代码更具可读性,有些人会说更容易使用.

#include <glob.h> // glob(), globfree()
#include <string.h> // memset()
#include <vector>
#include <stdexcept>
#include <string>
#include <sstream>

std::vector<std::string> glob(const std::string& pattern) {
    using namespace std;

    // glob struct resides on the stack
    glob_t glob_result;
    memset(&glob_result, 0, sizeof(glob_result));

    // do the glob operation
    int return_value = glob(pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
    if(return_value != 0) {
        globfree(&glob_result);
        stringstream ss;
        ss << "glob() failed with return_value " << return_value << endl;
        throw std::runtime_error(ss.str());
    }

    // collect all the filenames into a std::list<std::string>
    vector<string> filenames;
    for(size_t i = 0; i < glob_result.gl_pathc; ++i) {
        filenames.push_back(string(glob_result.gl_pathv[i]));
    }

    // cleanup
    globfree(&glob_result);

    // done
    return filenames;
}
Run Code Online (Sandbox Code Playgroud)

  • 这不检查任何错误,并且如果任何向量操作抛出则会泄漏内存 (3认同)

sth*_*sth 7

您可以使用glob()POSIX库函数.


art*_*ise 7

对于 C++17 标准的较新代码,std::filesystem存在并且它可以使用std::filesystem::directory_iterator递归版本来实现这一点。您必须手动实现模式匹配。例如,C++11正则表达式库。这将可移植到任何支持 C++17 的平台。

std::filesystem::path folder("/some/path/");
if(!std::filesystem::is_directory(folder))
{
    throw std::runtime_error(folder.string() + " is not a folder");
}
std::vector<std::string> file_list;

for (const auto& entry : std::filesystem::directory_iterator(folder))
{
    const auto full_name = entry.path().string();

    if (entry.is_regular_file())
    {
       const auto base_name = entry.path().filename().string();
       /* Match the file, probably std::regex_match.. */
       if(match)
            file_list.push_back(full_name);
    }
}
return file_list;
Run Code Online (Sandbox Code Playgroud)

对于非 C++17 情况,boost 中也实现了类似的 API。 std::string::compare()可能足以找到匹配项,包括多个调用,并且仅使用lenpos参数来匹配子字符串。


szx*_*szx 6

我为Windows和Linux 编写了一个简单的glob库(可能也适用于其他*nixes),前一段时间我很无聊,随意使用它.

用法示例:

#include <iostream>
#include "glob.h"

int main(int argc, char **argv) {
  glob::Glob glob(argv[1]);
  while (glob) {
    std::cout << glob.GetFileName() << std::endl;
    glob.Next();
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果有人使用构建系统并且包含使用 &lt;&gt; 而不是“”,则此标头名称可能会在 Unix 系统上发生冲突 (2认同)