significado - La manera más eficiente de procesar argumentos desde la línea de comandos en C++
Sugerencias para el procesamiento de argumentos de línea de comandos en C ++ de manera eficiente:
Nota : solo para Windows específico
1: #include <iostream.h>
2: int main(int argc, char **argv)
En lugar de, por ejemplo:
if ( argc != 3 ) {
....
}
Saludos
Si no quieres usar boost, te recomendaría esta pequeña clase de ayuda.
Sugeriría usar una biblioteca. Está el clásico y venerable getopt y estoy seguro de otros.
Hay una serie de buenas bibliotecas disponibles.
Boost Program Options es una solución bastante pesada, porque agregarla a tu proyecto requiere que desarrolles boost, y la sintaxis es algo confusa (en mi opinión). Sin embargo, puede hacer prácticamente todo, incluso teniendo las opciones de línea de comando anulando las establecidas en los archivos de configuración.
SimpleOpt es un procesador de línea de comandos bastante completo pero simple. Es un archivo único y tiene una estructura simple, pero solo maneja el análisis sintáctico de la línea de comando en opciones, usted tiene que hacer todo el tipo y la verificación de rango. Es bueno tanto para Windows como para Unix y también viene con una versión de glob para Windows.
getopt está disponible en Windows. Es lo mismo que en las máquinas Unix, pero a menudo es una biblioteca GPL.
Si solo quieres procesar las opciones de línea de comando, la forma más fácil es poner:
vector<string> args(argv + 1, argv + argc);
en la parte superior de tu main()
. Esto copia todos los argumentos de línea de comandos en un vector de std::string
s. Entonces puede usar ==
para comparar cadenas fácilmente, en lugar de interminables llamadas strcmp()
. Por ejemplo:
int main(int argc, char **argv) {
vector<string> args(argv + 1, argv + argc);
string infname, outfname;
// Loop over command-line args
// (Actually I usually use an ordinary integer loop variable and compare
// args[i] instead of *i -- don''t tell anyone! ;)
for (vector<string>::iterator i = args.begin(); i != args.end(); ++i) {
if (*i == "-h" || *i == "--help") {
cout << "Syntax: foomatic -i <infile> -o <outfile>" << endl;
return 0;
} else if (*i == "-i") {
infname = *++i;
} else if (*i == "-o") {
outfname = *++i;
}
}
}
[EDIT: me di cuenta de que estaba copiando argv[0]
, el nombre del programa, en args
- fixed.]
Esta es mi forma favorita de hacer la línea de comando, especialmente, pero definitivamente no solo cuando la eficiencia es un problema. Puede parecer excesivo, pero creo que hay pocas desventajas en este exceso.
Utilice gperf para un procesamiento eficiente de líneas de comando C / C ++
Desventajas:
- Primero debe ejecutar una herramienta diferente para generar el código de una tabla hash en C / C ++.
- No es compatible con interfaces de línea de comando específicas. Por ejemplo, el sistema de taquigrafía posix "-xyz" que declara múltiples opciones con un solo trazo sería difícil de implementar.
Ventajas:
- Sus opciones de línea de comando se almacenan por separado de su código C ++ (en un archivo de configuración separado, que no necesita ser leído en tiempo de ejecución, solo en tiempo de compilación).
- Todo lo que tienes en tu código es exactamente un cambio (activar los valores enum) para descubrir qué opción tienes
- La eficiencia es O (n) donde n es el número de opciones en la línea de comando y el número de opciones posibles es irrelevante. La parte más lenta es posiblemente la implementación del conmutador (a veces los compiladores tienden a implementarlos como si fueran bloques, lo que reduce su eficacia, aunque es poco probable si elige valores contiguos, consulte: este artículo sobre la eficiencia del conmutador )
- La memoria asignada para almacenar las palabras clave es precisamente lo suficientemente grande para el conjunto de palabras clave y no más grande.
- También funciona en C
Usando un eclipse tipo IDE probablemente puedas automatizar el proceso de ejecutar gperf, así que lo único que tendrías que hacer es agregar una opción al archivo de configuración y a tu declaración de cambio y presionar compilar ...
Usé un archivo por lotes para ejecutar gperf y hacer algunas tareas de limpieza y agregar guardias include con sed (en el archivo .hpp generado por gperf) ...
Por lo tanto, código extremadamente conciso y limpio dentro de su software y un archivo de tabla hash generado automáticamente que realmente no necesita cambiar manualmente. Dudo que boost :: program_options lo superara incluso sin eficiencia como prioridad.
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.