c++ - programacion - principales librerias en lenguaje c
¿Qué bibliotecas de analizador de parámetros existen para C++? (13)
Me gustaría pasar parámetros a mi programa C ++ de la siguiente manera:
./myprog --setting=value
¿Hay alguna biblioteca que me ayude a hacer esto fácilmente?
Ver también ayudantes de análisis argumental para C y Unix
Creo que GNU GetOpt no es demasiado inmediato para usar.
QT y Boost podrían ser una solución, pero necesita descargar y compilar una gran cantidad de código.
Así que implementé un analizador por mí mismo que produce un estándar :: mapa de parámetros.
Por ejemplo, llamar:
./myProgram -v -p 1234
mapa será:
["-v"][""]
["-p"]["1234"]
El uso es:
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; /* print 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;
}
GNU GetOpt .
Un ejemplo simple usando 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;
}
También puede usar optarg si tiene opciones que aceptan argumentos.
Hay parejas de analizadores de argumentos de C ++, es posible que desee probar este de http://clp.sourceforge.net/ , muy simple y conveniente.
Me resulta más fácil usar ezOptionParser . También es un único archivo de encabezado, no depende de nada más que STL, funciona para Windows y Linux (muy probablemente también para otras plataformas), no tiene curva de aprendizaje gracias a los ejemplos, tiene características que otras bibliotecas no tienen (como importación y exportación de archivos) con comentarios, nombres de opciones arbitrarias con delimitadores, formato de uso automático, etc.) y tiene licencia LGPL.
Podrías probar mi pequeño encabezado de opciones (166 loc tan fácilmente pirateable) options.hpp. Es una implementación de encabezado único y debe hacer lo que usted solicite. También imprime la página de ayuda automáticamente.
Pruebe la biblioteca CLPP. Es una biblioteca simple y flexible para el análisis de parámetros de línea de comandos. Encabezado solo y multiplataforma. Utiliza solo bibliotecas de C ++ y C ++ de C ++. En mi humilde opinión es más fácil que Boost.Program_options.
Biblioteca: http://sourceforge.net/projects/clp-parser/
26 de octubre de 2010: nuevo lanzamiento 2.0rc. Se corrigieron muchos errores, se reparó la refacturación completa del código fuente, la documentación, los ejemplos y los comentarios.
Qt 5.2 viene con una API de analizador de línea de comandos .
Pequeño ejemplo:
#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;
}
Ejemplo de salida
La pantalla de ayuda generada automáticamente:
$ ./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.
Salida de versión generada automáticamente:
$ ./qtopt -v ToolX 1.2
Algunas llamadas reales:
$ ./qtopt b1 -+ -o tmp blah.foo Input files: ("b1", "blah.foo") , verbose: true , output: "tmp" $ ./qtopt Input files: () , verbose: false , output: "out"
Un error de análisis:
$ ./qtopt --hlp Unknown option ''hlp''. $ echo $? 1
Conclusión
Si su programa ya usa las bibliotecas Qt (> = 5.2), su API de análisis de línea de comando es lo suficientemente conveniente para realizar el trabajo.
Tenga en cuenta que las opciones QApplication
Qt son consumidas por QApplication
antes de que se QApplication
el analizador de opciones.
Tocar mi propia bocina si puedo, también me gustaría sugerir echar un vistazo a una biblioteca de análisis de opciones que he escrito: dropt .
- Es una biblioteca C (con un contenedor C ++ si lo desea).
- Es liviano
- Es extensible (los tipos de argumentos personalizados se pueden agregar fácilmente y tienen el mismo nivel con los tipos de argumentos incorporados).
- Debe ser muy portable (está escrito en C estándar) sin dependencias (que no sea la biblioteca estándar de C).
- Tiene una licencia muy poco restrictiva (zlib / libpng).
Una característica que ofrece que muchos otros no tienen es la capacidad de anular las opciones anteriores. Por ejemplo, si tiene un alias de shell:
alias bar="foo --flag1 --flag2 --flag3"
y desea utilizar la bar
pero con --flag1
desactivado, le permite hacer:
bar --flag1=0
Y hay una biblioteca de Google disponible.
Realmente, el análisis de línea de comandos está "resuelto". Solo elige uno.
argstream
es bastante similar a boost.program_option
: permite vincular variables a las opciones, etc. Sin embargo, no maneja las opciones almacenadas en un archivo de configuración.