Question

Quelqu'un peut me aider avec la fonction getopt?

Quand je fais ce qui suit dans le 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;
    }
}

Je suis en cours d'exécution sur ce code RHEL3 qui utilise ancienne version libc. Je ne sais pas lequel pour être exact.

Maintenant, le problème est getopt ne fonctionne pas la deuxième fois avec argv2. Mais si je commente le premier appel getopt avec argv1, cela fonctionne.

Quelqu'un peut-il me dire ce que je fais mal ici?

Était-ce utile?

La solution

argv1 et 2 doivent se terminer à 0:

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

Modifier : OK, je lis la page de manuel getopt et je trouve ceci:

  

Le optind variable est l'indice de l'élément suivant à traiter dans argv. Le système initialise cette valeur          à 1. L'appelant peut le remettre à 1 pour redémarrer la numérisation du même argv, ou lors de la numérisation d'un nouveau vecteur d'argument.

Alors, ce qui rend optind = 1 entre les deux appels à getopt fait fonctionner comme prévu.

Autres conseils

La fonction getopt() utilise des variables globales, comme optind et optarg, pour stocker des informations d'état entre les appels. Après avoir terminé le traitement d'une série d'options, il y a gauche de données dans les variables qui pose des problèmes avec la prochaine série d'options. Vous pourriez éventuellement essayer de rétablir l'état de getopt entre les appels en effaçant les variables, mais je ne suis pas sûr que cela fonctionne puisque la fonction peut utiliser d'autres variables qui ne sont pas documentées et que vous ne savez jamais si vous les tous Gotten; En outre, il serait tout à fait nonportable (à savoir si la mise en œuvre des changements de getopt(), vos pauses de code). Voir la pour plus de détails. Mieux vaut ne pas utiliser getopt() pour plus d'un ensemble d'arguments dans un programme donné si vous pouvez l'aider.

Je ne sais pas s'il y a une fonction réelle pour réinitialiser l'état de getopt (ou peut-être une version rentrante de la fonction, ce qui vous permet de stocker l'état dans vos propres variables) ... Je me souviens avoir vu quelque chose comme ça une fois, mais je ne le trouve pas maintenant que je regarde: - /

Comme indiqué dans la page de manuel:

"Un programme qui scanne plusieurs vecteurs d'argument, ou réanalyse le même vecteur plus d'une fois, et veut utiliser des extensions GNU tels que « + » et « - » au début de optstring ou modifie la valeur de POSIXLY_CORRECT entre les balayages, doit réinitialiser getopt () en remettant à zéro optind à 0, au lieu de la valeur traditionnelle de 1. (Remise à 0 force l'invocation d'une routine d'initialisation interne qui vérifie de nouveau POSIXLY_CORRECT et vérifie les extensions GNU en optstring.) "

Y at-il des raisons pour lesquelles vous ne l'utilisez getopt_long () à la place? Sur la plupart des plates-formes, getopt () appelle simplement _getopt_long () avec un interrupteur pour désactiver les arguments longs. C'est le cas avec presque toutes les plateformes que je connaisse (encore en cours d'utilisation), y compris Linux, BSD et même émergents systèmes d'exploitation comme HELENOS -, je sais, je suis celui qui a porté getopt à son libc:)

Il est beaucoup plus facile sur quelqu'un qui utilise votre programme pour avoir des options longues au moins jusqu'à ce qu'ils soient utilisés pour l'utiliser.

getopt_long () vous permettra d'utiliser deux (ou plus) des indices d'options qui peuvent rester « en direct » après leur fait des arguments de traitement, seul le interne (global, non-rentrants) il faudrait un nouveau réglage qui est pas une grosse affaire.

Cela vous permet de comparer facilement le nombre d'arguments au nombre d'options réellement passé dans les deux invocations avec de nombreux autres avantages .. s'il vous plaît envisager ne pas utiliser l'interface vétuste.

Regardez getopt.h, vous verrez ce que je veux dire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top