我想在以下模式中检索此模式后面的所有匹配路径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)
对于 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()可能足以找到匹配项,包括多个调用,并且仅使用len和pos参数来匹配子字符串。
我为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)