Je voudrais passer des parameters à mon programme C ++ de la manière suivante:
./myprog --setting=value
Y a-t-il des bibliothèques qui vont m’aider à le faire facilement?
Voir aussi Aides à l’parsing d’arguments pour C et Unix
Boost.Program_options
GNU GetOpt .
Un exemple simple utilisant GetOpt:
// C/C++ Libraries: #include #include #include // Namespaces: using namespace std; int main(int argc, char** argv) { int opt; bool flagA = false; bool flagB = false; // Shut GetOpt error messages down (return '?'): opterr = 0; // Resortingeve the options: while ( (opt = getopt(argc, argv, "ab")) != -1 ) { // for each option... switch ( opt ) { case 'a': flagA = true; break; case 'b': flagB = true; break; case '?': // unknown option... cerr << "Unknown option: '" << char(optopt) << "'!" << endl; break; } } // Debug: cout << "flagA = " << flagA << endl; cout << "flagB = " << flagB << endl; return 0; }
Vous pouvez également utiliser optarg si vous avez des options qui acceptent des arguments.
TCLAP
est un design léger vraiment agréable et facile à utiliser: http://tclap.sourceforge.net/
Je trouve plus facile d’utiliser ezOptionParser . C’est aussi un fichier d’en-tête unique, ne dépend de rien, mais STL, fonctionne pour Windows et Linux (très probablement d’autres plateformes), n’a pas de courbe d’apprentissage grâce aux exemples, a des fonctionnalités que d’autres bibliothèques (import / export de fichiers) avec des commentaires, des noms d’options arbitraires avec des délimiteurs, un formatage automatique, etc.), et est sous licence LGPL.
Et il existe une bibliothèque Google disponible.
En réalité, l’parsing de ligne de commande est “résolue”. Choisissez-en un.
Il y a ces outils dans la bibliothèque GNU C, qui inclut GetOpt .
Si vous utilisez Qt et comme l’interface GetOpt , froglogic a publié une interface intéressante ici .
Je pense que GNU GetOpt n’est pas trop immédiat pour être utilisé.
QT et Boost pourraient être une solution, mais vous devez télécharger et comstackr beaucoup de code.
J’ai donc implémenté un parsingur par moi-même qui produit une std :: map de parameters.
Par exemple, appeler:
./myProgram -v -p 1234
la carte sera:
["-v"][""] ["-p"]["1234"]
Utilisation est:
int main(int argc, char *argv[]) { MainOptions mo(argc, argv); MainOptions::Option* opt = mo.getParamFromKey("-p"); const ssortingng type = opt ? (*opt).second : ""; cout << type << endl; /* print 1234 */ /* your check code */ }
MainOptions.h
#ifndef MAINOPTIONS_H_ #define MAINOPTIONS_H_ #include
MainOptions.cpp
#include "MainOptions.h" #include using namespace std; MainOptions::MainOptions(int argc, char* argv[]) : argc_(argc), argv_(argv) { appName_ = argv_[0]; this->parse(); } MainOptions::~MainOptions() { } std::ssortingng MainOptions::getAppName() const { return appName_; } void MainOptions::parse() { typedef pair Option; Option* option = new pair(); for (const char* const * i = this->begin() + 1; i != this->end(); i++) { const ssortingng p = *i; if (option->first == "" && p[0] == '-') { option->first = p; if (i == this->last()) { options_.insert(Option(option->first, option->second)); } continue; } else if (option->first != "" && p[0] == '-') { option->second = "null"; /* or leave empty? */ options_.insert(Option(option->first, option->second)); option->first = p; option->second = ""; if (i == this->last()) { options_.insert(Option(option->first, option->second)); } continue; } else if (option->first != "") { option->second = p; options_.insert(Option(option->first, option->second)); option->first = ""; option->second = ""; continue; } } } void MainOptions::printOptions() const { std::map::const_iterator m = options_.begin(); int i = 0; if (options_.empty()) { cout << "No parameters\n"; } for (; m != options_.end(); m++, ++i) { cout << "Parameter [" << i << "] [" << (*m).first << " " << (*m).second << "]\n"; } } const char* const *MainOptions::begin() const { return argv_; } const char* const *MainOptions::end() const { return argv_ + argc_; } const char* const *MainOptions::last() const { return argv_ + argc_ - 1; } bool MainOptions::hasKey(const std::string& key) const { return options_.find(key) != options_.end(); } MainOptions::Option* MainOptions::getParamFromKey( const std::string& key) const { const Options::const_iterator i = options_.find(key); MainOptions::Option* o = 0; if (i != options_.end()) { o = new MainOptions::Option((*i).first, (*i).second); } return o; }
Si je peux me permettre de parler de mon propre cor, je voudrais également suggérer de jeter un coup d’œil à une bibliothèque d’parsing d’options que j’ai écrite: dropt .
L’une des fonctionnalités offertes par beaucoup d’autres est la possibilité de remplacer les options précédentes. Par exemple, si vous avez un alias de shell:
alias bar="foo --flag1 --flag2 --flag3"
et vous voulez utiliser la bar
mais avec --flag1
désactivé, cela vous permet de faire:
bar --flag1=0
argstream
est assez similaire à boost.program_option
: il permet de lier des variables aux options, etc. Cependant, il ne gère pas les options stockées dans un fichier de configuration.
Essayez la bibliothèque CLPP. C’est une bibliothèque simple et flexible pour l’parsing des parameters de ligne de commande. En-tête uniquement et multiplateforme. Utilise uniquement les bibliothèques ISO C ++ et Boost C ++. IMHO c’est plus facile que Boost.Program_options.
Bibliothèque: http://sourceforge.net/projects/clp-parser/
26 octobre 2010 – nouvelle version 2.0rc. De nombreux bogues corrigés, la refactorisation complète du code source, de la documentation, des exemples et des commentaires ont été corrigés.
Qt 5.2 est livré avec une API d’parsing de ligne de commande .
Petit exemple:
#include #include #include int main(int argc, char **argv) { QCoreApplication app(argc, argv); app.setApplicationName("ToolX"); app.setApplicationVersion("1.2"); QCommandLineParser parser; parser.setApplicationDescription("Tool for doing X."); parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument("infile", QCoreApplication::translate("main", "Input file.")); QCommandLineOption verbose_opt("+", QCoreApplication::translate("main", "be verbose")); parser.addOption(verbose_opt); QCommandLineOption out_opt(QSsortingngList() << "o" << "output", QCoreApplication::translate("main", "Output file."), QCoreApplication::translate("main", "filename"), // value name QCoreApplication::translate("main", "out") // default value ); parser.addOption(out_opt); // exits on error parser.process(app); const QStringList args = parser.positionalArguments(); qDebug() << "Input files: " << args << ", verbose: " << parser.isSet(verbose_opt) << ", output: " << parser.value(out_opt) << '\n'; return 0; }
L'écran d'aide généré automatiquement:
$ ./qtopt -h Utilisation: ./qtopt [options] infile Outil pour faire X. Options: -h, --help Affiche cette aide. -v, --version Affiche les informations de version. - + être verbeux -o, --output Fichier de sortie. Arguments: Fichier d'entrée infile.
Sortie de la version générée automatiquement:
$ ./qtopt -v ToolX 1.2
Quelques vrais appels:
$ ./qtopt b1 - + -o tmp blah.foo Fichiers d'entrée: ("b1", "blah.foo"), verbose: true, sortie: "tmp" $ ./qtopt Fichiers d'entrée: (), verbose: false, output: "out"
Une erreur d'parsing:
$ ./qtopt --hlp Option inconnue "hlp". $ echo $? 1
Si votre programme utilise déjà les bibliothèques Qt (> = 5.2), son API d'parsing de ligne de commande est suffisamment pratique pour faire le travail.
Sachez que les options Qt intégrées sont utilisées par QApplication
avant que l’parsingur d’option ne s’exécute.
Vous pouvez essayer mon petit en- tête d’ options (166 loc facilement piratable) options.hpp . C’est une implémentation d’en-tête unique et devrait faire ce que vous demandez. Il imprime également la page d’aide automatiquement.
Il existe plusieurs parsingurs d’argument C ++, vous pouvez essayer celui-ci à partir de http://clp.sourceforge.net/ , très simple et pratique.