Quels sont les paramètres des bibliothèques d'analyseur pour C++? [fermé]
j'aimerais passer des paramètres à mon programme C++ de la manière suivante:
./myprog --setting=value
y a-t-il des bibliothèques qui peuvent m'aider à le faire facilement?
Voir aussi Argument-l'analyse des aides pour C et Unix
13 réponses
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 un design très léger et facile à utiliser:
http://tclap.sourceforge.net /
, je trouve ça plus facile à utiliser ezOptionParser . C'est aussi un fichier d'en-tête unique, 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 d'autres bibliothèques ne le font pas (comme l'importation/exportation de fichier avec des commentaires, les noms d'options arbitraires avec des délimiteurs, le formatage auto usage, etc), et est sous licence LGPL.
et il y a un Google library disponible.
vraiment, l'analyse en ligne de commande est "résolue."Simplement en choisir un.
il y a ces outils dans la bibliothèque GNU C, qui comprend GetOpt .
si vous utilisez Qt et comme l'interface GetOpt, froglogic a publié une interface agréable ici .
je pense que GNU GetOpt n'est pas trop immédiat à utiliser.
Qt et Boost pourrait être une solution, mais vous devez télécharger et compiler beaucoup de code.
donc j'ai implémenté un analyseur par moi-même qui produit un std::map
par exemple, appelant:
./myProgram -v -p 1234
carte sera:
["-v"][""]
["-p"]["1234"]
Usage:
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;
}
en klaxonnant si je peux me permettre, j'aimerais aussi suggérer de jeter un oeil à une bibliothèque d'analyse d'options que j'ai écrite: dropt .
- c'est une bibliothèque C (avec un wrapper C++ si désiré).
- c'est léger.
- c'est extensible (les types d'arguments personnalisés peuvent être facilement ajoutés et ont un pied d'égalité avec les types d'arguments intégrés).
- il devrait être très portable (il est écrit en standard C) sans dépendances (autre que la bibliothèque standard C).
- il a une licence très sans restriction (zlib/libpng).
une caractéristique qu'il offre que beaucoup d'autres ne le font pas est la capacité de passer outre à des options plus anciennes. Par exemple, si vous avez un shell alias:
alias bar="foo --flag1 --flag2 --flag3"
et vous voulez utiliser bar
mais avec --flag1
désactivé, il vous permet de faire:
bar --flag1=0
argstream
est assez similaire à boost.program_option
: il permet de lier des variables à des 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'analyse des paramètres en ligne de commande. En-tête seulement et multiplateformes. Utilise les bibliothèques ISO C++ et Boost C++ uniquement. IMHO il est plus facile que Boost.Program_options.
Bibliothèque: http://sourceforge.net/projects/clp-parser /
26 octobre 2010 - nouvelle version 2.0 rc. Beaucoup de bugs corrigés, le remaniement complet du code source, la documentation, les exemples et les commentaires ont été correct.
Qt 5.2 est fourni avec un parser API 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;
}
exemple de sortie
l'écran d'aide généré automatiquement:
$ ./qtopt -h Usage: ./qtopt [options] infile Tool for doing X. Options: -h, --help Displays this help. -v, --version Displays version information. -+ be verbose -o, --output Output file. Arguments: infile Input file.
sortie de version générée automatiquement:
$ ./qtopt -v ToolX 1.2
Certains de véritables appels:
$ ./qtopt b1 -+ -o tmp blah.foo Input files: ("b1", "blah.foo") , verbose: true , output: "tmp" $ ./qtopt Input files: () , verbose: false , output: "out"
une erreur d'analyse:
$ ./qtopt --hlp Unknown option 'hlp'. $ echo $? 1
Conclusion
si votre programme utilise déjà les bibliothèques Qt (>= 5.2), son API de parsing en ligne de commande est assez pratique pour faire le travail.
soyez conscient que les options QT intégrées sont consommées par QApplication
avant que l'analyseur d'Options ne démarre.
Vous pouvez essayer mon petit options de l'en-tête (166 loc si facilement piratable) options.hpp . C'est une implémentation d'en-tête unique et devrait faire ce que vous demandez. Il vous imprime également la page d'aide automatiquement.
il y a un couple d'analyseurs d'arguments C++ là-bas, vous pouvez essayer celui-ci de http://clp.sourceforge.net / , très simple et pratique.