Me gustaría pasar parámetros a mi progtwig 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
Boost.Program_options
GNU GetOpt .
Un ejemplo simple usando 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; // 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.
TCLAP
es un diseño liviano realmente agradable y fácil de usar: http://tclap.sourceforge.net/
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.
Y hay una biblioteca de Google disponible.
Realmente, el análisis de línea de comandos está “resuelto”. Solo elige uno.
Estas herramientas se encuentran en la Biblioteca C de GNU, que incluye GetOpt .
Si está utilizando Qt y le gusta la interfaz GetOpt , froglogic ha publicado una interfaz agradable aquí .
Creo que GNU GetOpt no es demasiado inmediato para usar.
QT y Boost podrían ser una solución, pero necesita descargar y comstackr 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
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::string 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 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::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; }
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 .
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
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.
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 #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(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; }
La pantalla de ayuda generada automáticamente:
$ ./qtopt -h Uso: ./qtopt [opciones] infile Herramienta para hacer X. Opciones: -h, --help Muestra esta ayuda. -v, --version Muestra información de la versión. - + ser detallado -o, --output de salida. Argumentos: archivo de entrada de archivo.
Salida de versión generada automáticamente:
$ ./qtopt -v ToolX 1.2
Algunas llamadas reales:
$ ./qtopt b1 - + -o tmp blah.foo Archivos de entrada: ("b1", "blah.foo"), verboso: verdadero, salida: "tmp" $ ./qtopt Archivos de entrada: (), verboso: falso, salida: "fuera"
Un error de análisis:
$ ./qtopt --hlp Opción desconocida 'hlp'. $ echo $? 1
Si su progtwig 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.
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.
Hay parejas de analizadores de argumentos de C ++, es posible que desee probar este de http://clp.sourceforge.net/ , muy simple y conveniente.