2010-05-11 8 views
3

Comment implémenter le ls "filename_ [0-5] [3-4]?" comme classe? Le résultat que je voudrais stocker dans le vector.C++ imitation de commandes similaires à

Actuellement, je me sers du système () qui appelle ls, mais ce n'est pas portable sous MS.

merci, Arman.

+0

Est-ce un modèle glob? La partie '[4-3]' du motif peut ne pas correspondre à ce que vous attendiez. Il évalue au littéral '[4-3]', ainsi peut-être vous voulez dire '[3-4]' qui signifie 3 ou 4. – wilhelmtell

+0

Oh oui, vrai désolé mon mauvais. – Arman

+0

Je ne suis pas sûr comment 'ls' ressemble à une classe __. Pour moi, il ressemble plus à un algorithme, donc une fonction. – sbi

Répondre

5

Les fichiers liste programme suivant dans le répertoire courant dont le nom correspond à l'expression régulière filename_[0-5][34]:

#include <boost/filesystem.hpp> 
#include <boost/regex.hpp> // also functional,iostream,iterator,string 
namespace bfs = boost::filesystem; 

struct match : public std::unary_function<bfs::directory_entry,bool> { 
    bool operator()(const bfs::directory_entry& d) const { 
     const std::string pat("filename_[0-5][34]"); 
     std::string fn(d.filename()); 
     return boost::regex_match(fn.begin(), fn.end(), boost::regex(pat)); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    transform_if(bfs::directory_iterator("."), bfs::directory_iterator(), 
       std::ostream_iterator<std::string>(std::cout, "\n"), 
       match(), 
       mem_fun_ref(&bfs::directory_entry::filename)); 
    return 0; 
} 

J'omis la définition de transform_if() par souci de concision. Ce n'est pas une fonction standard, mais elle devrait être simple à mettre en œuvre.

+0

Lorsque vous essayez de compiler ceci, n'oubliez pas d'ajouter le 'include 'manquant dans le commentaire, définissez le' transform_if() 'manquant (je peux vous donner un coup de main si nécessaire), et le lien avec le système de fichiers et regex bibliothèques. Avec g ++, vous pouvez lier ces bibliothèques en spécifiant '-lboost_filesystem -lboost_system -lboost_regex' dans la ligne de commande. Vous n'aurez peut-être pas besoin de l'indicateur '-lboost_system' si vous utilisez Linux. – wilhelmtell

+0

C'est incroyable !!! Fonctionne sur Linux et MS. Merci! BTW: le transform_if J'utilise comme ceci: template Out transform_if (En premier lieu, dernier, Out res, Pred p, op op) \t { \t while (premier!= dernier) { \t \t si (p (* premier)) \t \t \t * res = op (* en premier); \t \t ++ d'abord; ++ res; \t \t} \t return res; \t} – Arman

+0

@Arman Yep, ça a l'air vrai! – wilhelmtell

2

Vous pouvez utiliser le système de fichiers boost :: qui permet de récupérer des fichiers dans un répertoire de manière portable.

Ensuite, vous pouvez vérifier les fichiers par rapport à une expression régulière avec boost :: regex par exemple pour ne conserver que ceux qui correspondent à votre modèle.

+0

Merci, je ne suis pas familier avec regex, pourriez-vous s'il vous plaît donner un exemple d'analyse de mon modèle? – Arman

+1

Vous pouvez consulter la documentation de boost: http://www.boost.org/doc/libs/1_43_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html autant que je me souvienne, il sera ne pas être très différent de "filename_ [0-5] [3-4]" – Nikko

+0

Ce modèle de glob arrive à être aussi une expression régulière, en fait. Vous pouvez changer '[3-4]' '[34]' et garder le même sens, mais à part cela, il reste le même. – wilhelmtell

0

La solution boost est portable, mais pas optimale sous Windows. La raison en est qu'il appelle FindFirstFile("*.*") et retourne donc tout. Étant donné le modèle de globbing, il serait plus efficace d'appeler FindFirstFile("filename_?*.*"). Vous devrez toujours filtrer les résultats (en utilisant par exemple Boost :: regex) mais cela exclurait de nombreux fichiers qui ne peuvent pas correspondre. De plus, en utilisant l'une ou l'autre méthode, n'oubliez pas de filtrer les répertoires avant de faire la correspondance avec les expressions rationnelles. La vérification si une entrée est un répertoire est assez bon marché.

+0

Vraiment? Même avec 'boost :: filesystem :: directory_iterator'? Je peux voir que ce n'est pas le cas sur OS X. – wilhelmtell

+0

Je suis probablement mal compris votre commentaire, mais je ne vois pas pourquoi OSX compte quand j'explique où Boost sur Windows n'est pas optimal. – MSalters

+0

Je ne vous contredis pas. Je viens de dire que ce n'est pas le cas sur OS X. Chill. – wilhelmtell