5 votes

Getopt shift optarg

Je dois appeler mon programme comme suit :

./program hello -r foo bar

Je retire hello de argv[1], mais j'ai des problèmes avec value bar, et devrais-je changer "r :" par quelque chose d'autre ?

while((c = getopt(argc, argv, "r:")) != -1){
   switch(i){
   ...
   case 'r':
     var_foo = optarg;
     //shell like argument shift here?
     var_bar = optarg;
     break;
...}

Je sais que je peux le faire en passant par argv, mais y a-t-il un moyen de le faire avec getopt de la même manière que dans bash ?

Merci.

8voto

Kerrek SB Points 194696

bar n'est pas un argument d'option aux yeux de l getopt . Au contraire, GNU getopt réarrange les arguments positionnels de sorte qu'à la fin du traitement, vous ayez argv[3] étant "hello" et argv[4] étant "bar". Fondamentalement, lorsque vous avez terminé le getopting, vous avez encore des arguments de position [optind, argc) à traiter :

int main(int argc, char * argv[])
{
     {
         int c;
         while ((c = getopt(argc, argv, ...)) != -1) { /* ... */ }
     }

     for (int i = optind; i != argc; ++i)
     {
         // have positional argument argv[i]
     }
}

3voto

Jonathan Leffler Points 299946

Cela dépend si vous utilisez GNU getopt() ou non, et si oui, si POSIXLY_CORRECT est défini dans l'environnement.

Classiquement (c'est-à-dire sans GNU getopt() ), tous les arguments d'option doivent précéder les arguments non optionnels (nom de fichier). Cela signifie que vous avez quatre arguments non optionnels.

Si vous disposez de GNU getopt() et n'ont pas POSIXLY_CORRECT set, il traitera les arguments d'option n'importe où sur la ligne de commande. Dans ce cas, vous n'avez qu'une seule option, -r avec la valeur de l'argument foo et deux arguments non optionnels ( hello y bar ).

Pour obtenir Classic getopt() de reconnaître la -r il faudrait exiger le premier argument (non optionnel) et ensuite seulement appeler getopt() du tout :

int main(int argc, char **argv)
{
    char *cmd = argv[1];
    int   opt;

    argv[1] = argv[0];
    argv++;
    argc--;

    while ((opt = getopt(argv, argc, "r:")) != EOF)
    {
        switch (opt)
        {
        case 'r':
            ...capture optarg...
            break;
        default:
            ...report error....
            break;
        }
    }

    for (int i = optind; i < argc; i++)
        process_non_option_argument(cmd, argv[i]);

    return(0);
}

GNU getopt peut également renvoyer des arguments sans option si vous l'autorisez à le faire. En dehors de cela, la fonction bar sera toujours traité comme un argument de non-option.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X