2010-10-15 11 views
12

Mi argumento es como estoC getopt valor múltiple

./a.out -i file1 file2 file3 

¿Cómo puedo utilizar yo getopt() para obtener 3 (o más) archivos de entrada? que estoy haciendo algo como esto:

while ((opt = getopt(argc, argv, "i:xyz.."))!= -1){ 
    case 'i': 
    input = optarg; 
    break; 
    ... 
} 

que obtener sólo el file1; cómo obtener file2, file3?

+0

Tenga en cuenta que la cuestión [Suministro de dos argumentos para la opción de línea de comandos usando 'getopt()'] (http: // stackoverflow. com/questions/8559391/supplying-two-arguments-to-command-line-option-using-getopt /) proporciona algunas posibilidades que no se mencionan aquí. –

+0

Las respuestas a continuación que modifican 'optind' en el código del programa están pisando hielo delgado. No existe ningún requisito documentado de que 'getopt()' se comporte si modifica 'optind' u' optarg' en el código de llamada. De acuerdo, la mayoría de las implementaciones actuales y plausibles no tendrán un problema, pero una implementación hipotética podría registrar su estado interno en variables no globales, y simplemente establecer las globales a medida que regresa. Dicha implementación cumpliría con la especificación POSIX para ['getopt()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html), pero el retoque que se muestra no funcionaría. –

Respuesta

9

Si debe, puede comenzar en argv[optind] e incrementar optind usted mismo. Sin embargo, recomendaría no hacerlo ya que considero que la sintaxis es de mala calidad. (¿Cómo sabría cuándo ha llegado al final de la lista? ¿Qué pasa si alguien tiene un archivo llamado con un - como el primer personaje?)

Creo que sería mejor cambiar su sintaxis a cualquiera :

/a.out -i file1 -i file2 -i file3 

o para tratar la lista de archivos como parámetros posicionales:

/a.out file1 file2 file3 
+0

Gracias jamesdlin miraré [optind] ya que tengo bastantes argumentos distintos de -i – w00d

5

Tenga en cuenta que la extensión de permutación argumento no conformes de glibc se romperá cualquier intento de utilizar varios argumentos para -i de esta manera. Y en sistemas que no sean de GNU, el "segundo argumento -i" se interpretará como el primer argumento sin opción, deteniendo cualquier análisis adicional de la opción. Con estos problemas en mente, dejaría getopt y escribiría su propio analizador de línea de comandos si desea usar esta sintaxis, ya que no es una sintaxis compatible con getopt.

23

Sé que esto es bastante antiguo, pero me encontré con esto en mi búsqueda de una solución.

while((command = getopt(argc, argv, "a:")) != -1){ 

    switch(command){ 
     case 'a': 

     (...) 

     optind--; 
     for(;optind < argc && *argv[optind] != '-'; optind++){ 
       DoSomething(argv[optind]);   
     } 

     break; 
    } 

encontré que int optind (extern utilizado por getopt()) apunta a la próxima posición después de la 'actual argv' seleccionado por getopt(); Es por eso que lo disminuyo al principio.

Primero de todo para bucle comprueba si el valor del argumento actual está dentro de límites de argv (argc es la longitud de matriz de modo última posición en array argv es argc-1). Segunda parte de & & se compara si el primer carácter del siguiente argumento es '-'. Si el primer carácter es '-', entonces nos quedamos sin los siguientes valores para el argumento actual, sino que argv [optind] es nuestro próximo valor. Y así sucesivamente hasta que el argv haya terminado o la discusión se quede sin valores.

Al final del incremento optind para verificar la siguiente argv.

Tenga en cuenta que debido a que estamos comprobando 'optind < argc' primera segunda parte de la condición no se ejecutará a menos primera parte es verdadero lo que no se preocupa de la lectura fuera de los límites de la matriz.

PD Soy un programador de C bastante nuevo, si alguien tiene alguna mejora o crítica, por favor compártelo.

+3

Esto es bastante antiguo, pero pensé que podría agregar una crítica. No solo debe verificar el '-', sino también asegurarse de que 'strlen (argv [optind])' sea igual a 2. Esto aseguraría que manejará adecuadamente los parámetros que comienzan con un guión. ¡Este código fue útil para mí! +1 – TheBat

3

miré, y probado el código anterior, pero me pareció que mi solución un poco más fácil y funcionó mejor para mí:

El manejo que quería era:

-m mux_i2c_group mux_i2c_out 

(2) argumentos necesarios.

Así es como filtró a cabo para mí:

case 'm': 
    mux_i2c_group = strtol(optarg, &ch_p, 0); 

    if (optind < argc && *argv[optind] != '-'){ 
     mux_i2c_out = strtol(argv[optind], NULL, 0); 
     optind++; 
    } else { 
     fprintf(stderr, "\n-m option require TWO arguments <mux_group> " 
         "<mux_out>\n\n"); 
     usage(); 
    } 

    use_mux_flag = 1; 
    break; 

Esta agarró el primer valor me forman como normal y luego se limitó por segundo, valor requerido.

1

Puede especificar sus archivos de entrada con un carácter que no sea de espacios en blanco, como una coma, e iterar a través de ellos.

Por ejemplo, si $ archivos = "archivo1, archivo2, file3" -

for i in ${files//,/ } ; do 
    ..do stuff with $i.. 
done