Pregunta

Puede alguien ayudarme con la función getopt?

Cuando hago lo siguiente en el principal:

char *argv1[] = {"testexec","-?"};
char *argv2[] = {"testexec","-m","arg1"};
int  cOption;
/* test for -? */

setvbuf(stdout,(char*)NULL,_IONBF,0);
printf("\n argv1 ");
while (( cOption = getopt (2, argv1, "m:t:n:fs?")) != -1) {
    switch(cOption){
        case 'm':
            printf("\n -m Arg : %s \n",optarg);
            break;
        case '?':
            printf("\n -? Arg ");
            break;
        case 'n':
            printf("\n -n Arg : %s \n",optarg);
            break;
    }
}

printf("\n argv2 ");

while (( cOption = getopt (3, argv2, "m:t:n:fs?")) != -1) {
    switch(cOption){
        case 'm':
            printf("\n -m Arg : %s \n",optarg);
            break;
        case '?':
            printf("\n -? Arg : %s \n",optarg);
            break;
        case 'n':
            printf("\n -n Arg : %s \n",optarg);
            break;
    }
}

Estoy corriendo este código en RHEL3 que utiliza vieja versión de libc. No sé cuál de ellos para ser exactos.

Ahora el problema es que no funciona getopt el segundo tiempo con argv2. Pero si comento hacia fuera la primera llamada getopt con argv1, funciona.

Puede alguien decirme qué estoy haciendo mal aquí?

¿Fue útil?

Solución

argv1 y 2 deben terminar en 0:

char* argv1[] = {"par1", "par2", 0};

Editar : OK, he leído la página del manual getopt y encontré esto:

  

El optind variable es el índice del siguiente elemento a procesar en argv. El sistema se inicia este valor          a 1. La persona que llama puede restablecer a 1 para reiniciar el escaneo de la misma argv, o cuando se explora un nuevo vector de argumento.

Por lo tanto, haciendo optind = 1 entre las dos llamadas al getopt hace que funcione como se espera.

Otros consejos

La función getopt() utiliza algunas variables globales, como optind y optarg, para almacenar información de estado entre las llamadas. Después de terminar de procesar un conjunto de opciones, no hay datos de izquierda en aquellas variables que están causando problemas con el siguiente conjunto de opciones. Usted podría tratar de restablecer el estado de getopt entre llamadas en la limpieza de las variables, pero no estoy seguro de que iba a funcionar ya que la función podría utilizar otras variables que no están documentadas y nunca se sabe si todos ellos habían conseguido; Además, sería absolutamente no portátil (es decir, si la implementación de cambios getopt(), su código). Vea la página del manual para más detalles. Mejor no usar getopt() para más de un conjunto de argumentos en un programa dado si puede evitarlo.

No estoy seguro de si hay una función real para restablecer el estado de getopt (o tal vez una versión reentrante de la función, lo que le permite almacenar el estado en sus propias variables) ... Me parece recordar haber visto algo por el estilo una vez, pero no puedo encontrar ahora que miro: - /

Como se indica en la página del manual:

"Un programa que escanea múltiples vectores de argumentos, o vuelve a explorar el mismo vector más de una vez, y quiere hacer uso de extensiones de GNU, como '+' y '-' en el inicio de optstring, o cambia el valor de POSIXLY_CORRECT entre exploraciones, debe reinicializar getopt () restableciendo optind a 0, en lugar del valor tradicional de 1. (Restablecimiento de 0 obliga a la invocación de una rutina de inicialización interna que vuelve a verificar POSIXLY_CORRECT y cheques para extensiones de GNU en optstring.) "

¿Hay alguna razón por la que no está utilizando getopt_long () en su lugar? En la mayoría de las plataformas, getopt () sólo llama _getopt_long () con un interruptor para desactivar argumentos largos. Ese es el caso con casi todas las plataformas, que yo sepa (todavía en uso), incluyendo Linux, BSD e incluso emergentes sistemas operativos como HelenOS -, lo sé, yo era el que portado getopt a su libc:)

Es mucho más fácil para personas que utilicen el programa para tener opciones de largo por lo menos hasta que se acostumbren a usarlo.

getopt_long () le permitirá utilizar dos (o más) los índices de opciones que pueden permanecer 'en vivo' después de que se hacen los argumentos de procesamiento, sólo el interno (, no reentrante global) uno tendría que ser re-fijo que no es gran cosa.

Esto le permite comparar fácilmente el número de argumentos con el número de opciones que se le pasan en ambas invocaciones con muchos otros beneficios .. por favor, considere la posibilidad de no utilizar la interfaz anticuada.

Mira getopt.h, verá lo que quiero decir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top