web-dev-qa-db-fra.com

Simple glob en C++ sur un système Unix?

Je veux récupérer tous les chemins correspondants en suivant ce modèle dans un vector<string>:

"/some/path/img*.png"

Comment puis-je simplement faire ça?

26
Benjamin Crouzier

J'ai ça dans mon Gist. J'ai créé un wrapper stl autour de glob pour qu'il renvoie le vecteur de chaîne et se charge de libérer le résultat de glob. Pas vraiment très efficace, mais ce code est un peu plus lisible et certains diraient plus facile à utiliser.

#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;
}
48
Piti Ongmongkolkul

Vous pouvez utiliser la fonction de bibliothèque glob() POSIX.

7
sth

J'ai écrit une simple bibliothèque glob pour Windows et Linux (qui fonctionne probablement aussi sur d'autres * nixes) il y a quelque temps, quand je m'ennuyais, n'hésitez pas à l'utiliser comme bon vous semble.

Exemple d'utilisation:

#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();
  }
}
6
szx

J'ai essayé les solutions ci-dessus sur Centos6 et j'ai découvert qu'il me fallait changer:

int ret = glob(pat.c_str(), 0, globerr, &glob_result);

(où "globerr" est une fonction de traitement d'erreur)

Sans le 0 explicite, j'ai l'erreur "GLOB_NOSPACE".

1
mousomer

Mostl probable http://www.boost.org/doc/libs/release/libs/regex/ est ce qui se trouve le plus près de chez vous. Il y a de bonnes chances que cela soit supporté en C++ 11.

0
rakesh