Je voudrais passer des paramètres à mon programme C++ de la manière suivante:
./myprog --setting=value
Y a-t-il des bibliothèques qui m'aideront à le faire facilement?
GNU GetOpt .
Un exemple simple utilisant GetOpt:
// C/C++ Libraries:
#include <string>
#include <iostream>
#include <unistd.h>
// 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;
// Retrieve 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 les arguments.
TCLAP
est une conception légère vraiment agréable et facile à utiliser: http://tclap.sourceforge.net/
Je trouve plus facile à utiliser ezOptionParser . C'est aussi un seul fichier d'en-tête, ne dépend de rien d'autre que STL, fonctionne pour Windows et Linux (très probablement d'autres plates-formes aussi), n'a pas de courbe d'apprentissage grâce aux exemples, a des fonctionnalités que d'autres bibliothèques ne font pas (comme l'importation/l'exportation de fichiers avec commentaires, noms d’option arbitraires avec délimiteurs, formatage automatique, etc.) et est sous licence LGPL.
Et il y a bibliothèque Google disponible.
Vraiment, l'analyse en ligne de commande est "résolue". Choisissez-en un.
Je pense que GNU GetOpt n'est pas trop immédiat à utiliser.
Qt et Boost pourraient être une solution, mais vous devez télécharger et compiler beaucoup de code.
J'ai donc implémenté un analyseur par moi-même qui produit un std :: map <std :: string, std :: string> de paramètres.
Par exemple, en appelant:
./myProgram -v -p 1234
la carte sera:
["-v"][""]
["-p"]["1234"]
L'utilisation est:
int main(int argc, char *argv[]) {
MainOptions mo(argc, argv);
MainOptions::Option* opt = mo.getParamFromKey("-p");
const string type = opt ? (*opt).second : "";
cout << type << endl; /* Prints 1234 */
/* Your check code */
}
MainOptions.h
#ifndef MAINOPTIONS_H_
#define MAINOPTIONS_H_
#include <map>
#include <string>
class MainOptions {
public:
typedef std::pair<std::string, std::string> Option;
MainOptions(int argc, char *argv[]);
virtual ~MainOptions();
std::string getAppName() const;
bool hasKey(const std::string&) const;
Option* getParamFromKey(const std::string&) const;
void printOptions() const;
private:
typedef std::map<std::string, std::string> Options;
void parse();
const char* const *begin() const;
const char* const *end() const;
const char* const *last() const;
Options options_;
int argc_;
char** argv_;
std::string appName_;
};
MainOptions.cpp
#include "MainOptions.h"
#include <iostream>
using namespace std;
MainOptions::MainOptions(int argc, char* argv[]) :
argc_(argc),
argv_(argv) {
appName_ = argv_[0];
this->parse();
}
MainOptions::~MainOptions() {
}
std::string MainOptions::getAppName() const {
return appName_;
}
void MainOptions::parse() {
typedef pair<string, string> Option;
Option* option = new pair<string, string>();
for (const char* const * i = this->begin() + 1; i != this->end(); i++) {
const string 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<std::string, std::string>::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 m'exprimer, je voudrais également suggérer de jeter un œil à une bibliothèque d'analyse d'options que j'ai écrite: dropt .
Une fonctionnalité qu'il offre que beaucoup d'autres ne sont pas la possibilité de remplacer les options précédentes. Par exemple, si vous avez un alias Shell:
alias bar="foo --flag1 --flag2 --flag3"
et vous voulez utiliser bar
mais avec--flag1
désactivé, il vous permet de faire:
bar --flag1=0
Essayez la bibliothèque CLPP. C'est une bibliothèque simple et flexible pour l'analyse des paramètres de ligne de commande. En-tête uniquement et multiplateforme. Utilise uniquement les bibliothèques ISO C++ et Boost C++. À mon humble avis, il est plus facile que Boost.Program_options.
Bibliothèque: http://sourceforge.net/projects/clp-parser/
26 octobre 2010 - nouvelle version 2.0rc. De nombreux bugs corrigés, refactoring complet du code source, documentation, exemples et commentaires ont été corrigés.
Qt 5.2 est livré avec une API de l'analyseur de ligne de commande .
Petit exemple:
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>
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(QStringList() << "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 détaillé -o, --output Fichier de sortie. Arguments: Infile Fichier d'entrée.
Sortie de 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"), verbeux: vrai, sortie: "tmp" $ ./qtopt Fichiers d'entrée: (), verbeux: faux, sortie: "out"
Une erreur d'analyse:
$ ./qtopt --hlp Option inconnue 'hlp'. $ echo $? 1
Si votre programme utilise déjà les bibliothèques Qt (> = 5.2), son API d'analyse de ligne de commande est suffisamment pratique pour faire le travail.
Sachez que les options Qt intégrées sont consommées par QApplication
avant l'exécution de l'analyseur d'option.
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.
Vous pouvez essayer mes petites options en-tête (166 loc si facilement piratables) options.hpp . Il s'agit d'une implémentation à en-tête unique et devrait faire ce que vous demandez. Il vous imprime également la page d'aide automatiquement.