IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Getopt et ses valeurs


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Getopt et ses valeurs
    Bonjour tout le monde
    J'ai un petit ennui avec getopt... J'essaye de recuperer plusieurs valeurs pour une option mais apparement les options suivantes ne sont plus prises en compte...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
      while ((c = getopt(argc, argv, "p:x:y:c:t:vn::" )) != EOF)
      {
          if (c == 'p')
        env.port  = atoi(optarg);
          else if (c == 'x')
        env.map_x = atoi(optarg);
          else if (c == 'y')
        env.map_y = atoi(optarg);
          else if (c == 'c')
        env.max_players = atoi(optarg);
          else if (c == 't')
        env.cronos = atoi(optarg);
          else if (c == 'v')
        env.verbose = 1;
          else if (c == 'n')
        {
          env.teams = xmalloc(3 * sizeof(*env.teams));
          env.teams[2] = "\0";
          env.teams[0] = strdup(optarg);
          optarg += (strlen(env.teams[0]) + 1);
          env.teams[1] = strdup(optarg);
        }
      }
    et je lance cette commande :
    ./serveur -p 39115 -x 666 -y 69 -v-n LoL Ookay -t 4242 -c 11

    Le resultat :

    map_x : 666
    map_y : 69
    port : 39115
    Team 1 : LoL
    Team 2 : Ookay
    verbose : 1
    max_players : 0
    cronos : 0

    En fait le getopt ignore toutes les options passees apres...


    Quelqu'un aurait il une petite idee ? Merci d'avance !

  2. #2
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Le format de description donne a getopt() n'est pas correct pour l'option -n. Contrairement a l'intuition, un double : ne signifie pas 'deux options suivent', mais que l'option est de la forme -n<first> <second>, sans espace entre -n et <first>.
    Ceci fonctionne (j'ai rajoute une troisieme option a -n pour montrer la bonne utilisation):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
     
    int main(int argc, char *argv[])
    {
      int c;
     
      while ((c = getopt(argc, argv, "p:x:y:c:t:vn:01" )) != EOF)
      {
        printf("%c: ", c);
        fflush(stdout);
     
        switch (c)
        {
          case 'p':
            printf("port = %d\n", atoi(optarg));
            break;
          case 'x':
            printf("map_x = %d\n", atoi(optarg));
            break;
          case 'y':
            printf("map_y = %d\n", atoi(optarg));
            break;
          case 'c':
            printf("max_players = %d\n", atoi(optarg));
            break;
          case 't':
            printf("cronos = %d\n", atoi(optarg));
            break;
          case 'v':
            printf("verbose switched on\n");
            break;
          case 'n':
            {
              char *p = optarg;
     
              printf("%s ", p);
              p += strlen(p) + 1;
              printf("%s ", p);
              p += strlen(p) + 1;
              printf("%s\n", p);
            }
            break;
        }
      }
     
      return 0;
    }
    Si j'appelle le programme ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    toto -p 39115 -x 666 -y 69 -v -n team1 team2 team3 -t 4242 -c 11
    j'obtiens bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    p: port = 39115
    x: map_x = 666
    y: map_y = 69
    v: verbose switched on
    n: team1 team2 team3
    t: cronos = 4242
    c: max_players = 11
    Derniere remarque: la fonction atoi() est desormais remplacee par strtol(). Aucun nouveau code ne doit utiliser atoi().

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci pour ta reponse
    Cependant...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    while ((c = getopt(argc, argv, "p:x:y:c:t:vn:0")) != EOF)
      {
          if (c == 'p')
        env->port  = atoi(optarg);
          else if (c == 'x')
        env->map_x = atoi(optarg);
          else if (c == 'y')
        env->map_y = atoi(optarg);
          else if (c == 'c')
        env->max_players = atoi(optarg);
          else if (c == 't')
        env->cronos = atoi(optarg);
          else if (c == 'v')
        env->verbose = 1;
          else if (c == 'n')
        {
          char *p = optarg;
     
          env->teams = xmalloc(3 * sizeof(*env->teams), env);
          env->teams[0] = strdup(p);
          p += strlen(p) + 1;
          env->teams[1] = strdup(p);
          env->teams[2] = "\0";
        }
      }
    Si je lance de cette maniere :
    ./serveur -p 39115 -n LoL Okket -x 22 -y 11 -v -t 100 -c 10

    le programme reste bloque en boucle infinie...

  4. #4
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Tu declares bien c comme etant un int? Si tu le declares comme char, c ne pourra jamais etre egal a EOF...

  5. #5
    Invité
    Invité(e)
    Par défaut
    Oui c'est bien un int ... En fait tant que le nom des equipes est passe en tan que dernier parametre, tout va bien ! Des qu'il est passe en premier ou autre parametre, le programme se bloque

  6. #6
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Je ne vois pas. L'erreur doit se produire ailleurs ou alors ton getopt() a un comportement inattendu, mais ce serait vraiment surprenant...

  7. #7
    Invité
    Invité(e)
    Par défaut
    Hum, je ne comprends pas tout moi meme... Hier, le programme bloquait purement et simplement... Maintenant, il bloque uniquement quand les equipes sont passees en premier paramtre, et m'affiche une erreur de malloc -_-'

    Enfin merci pour ton aide, apparement le getopt marche

  8. #8
    Invité
    Invité(e)
    Par défaut
    Hum, j'ai rien dit !
    Quand je fais un test avec uniquement la fonction appellant getopt, les valeurs retournees sont tout simplement... inexistantes -_-

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          get_options(ac, av, &env);
    La fonction est appellee avec ca... Et le code entier de la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    void    get_options(int argc, char **argv, t_env *env)
    {
      int    c;
     
      while ((c = getopt(argc, argv, "p:x:y:c:t:vn:0")) != EOF)
        {
          if (c == 'p')
        env->port  = atoi(optarg);
          else if (c == 'x')
        env->map_x = atoi(optarg);
          else if (c == 'y')
        env->map_y = atoi(optarg);
          else if (c == 'c')
        env->max_players = atoi(optarg);
          else if (c == 't')
        env->cronos = atoi(optarg);
          else if (c == 'v')
        env->verbose = 1;
          else if (c == 'n')
        {
          char *p = optarg;
     
          env->teams = xmalloc(3 * sizeof(*env->teams), env);
          env->teams[0] = strdup(p);
          p += strlen(p) + 1;
          env->teams[1] = strdup(p);
          env->teams[2] = '\0';
        }
        }
    }
    Quand je lui demande d'afficher les valeurs, tous les arguments apres les teams sont indefinis

    $> ./serveur -n LoL Okket -p 39115 -x 69 -y 69 -v -t 100 -c 12

    map_x : -1111509930
    map_y : -1111638016
    port : -1111523156
    Team 1 : LoL
    Team 2 : Okket
    verbose : 0
    max_players : 4
    cronos : -1111572064

    d'ailleurs, le max_players correspond a l'option -c, donc en theorie 12 et pas 4...


  9. #9
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Voici le code qui marche parfaitement chez moi. Je ne connais pas la fonction xmalloc(), donc j'ai simplifie ton code en evitant l'allocation dynamique (c'est peut-etre ton probleme).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
     
    /*
     * toto -p 39115 -x 666 -y 69 -v -n team1 team2 -t 4242 -c 11
     */
     
    typedef struct
    {
      long port;
      long map_x;
      long map_y;
      long max_players;
      long cronos;
      int verbose;
      char *teams[2];
    } t_env;
     
    static void get_options(int argc, char *argv[], t_env *env)
    {
      int c;
     
      while ((c = getopt(argc, argv, "p:x:y:c:t:vn:0" )) != EOF)
      {
        switch (c)
        {
          case 'p':
            env->port = strtol(optarg, NULL, 10);
            break;
          case 'x':
            env->map_x = strtol(optarg, NULL, 10);
            break;
          case 'y':
            env->map_y = strtol(optarg, NULL, 10);
            break;
          case 'c':
            env->max_players = strtol(optarg, NULL, 10);
            break;
          case 't':
            env->cronos = strtol(optarg, NULL, 10);
            break;
          case 'v':
            env->verbose = 1;
            break;
          case 'n':
            {
              char *p = optarg;
     
              env->teams[0] = strdup(p);
              p += strlen(p) + 1;
              env->teams[1] = strdup(p);
            }
            break;
        }
      }
    }
     
    int main(int argc, char *argv[])
    {
      t_env env = { 0, 0, 0, 0, 0, 0, {NULL, NULL} }; 
     
      get_options(argc, argv, &env);
     
      printf("map_x: %ld\n", env.map_x);
      printf("map_y: %ld\n", env.map_y);
      printf("port: %ld\n", env.port);
      printf("team 1: %s\n", env.teams[0]);
      printf("team 2: %s\n", env.teams[1]);
      printf("verbose: %d\n", env.verbose);
      printf("max_players: %ld\n", env.max_players);
      printf("cronos: %ld\n", env.cronos);
     
      free(env.teams[0]);
      free(env.teams[1]);
     
      return 0;
    }
    Essayons avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    toto -p 39115 -x 666 -y 69 -v -n team1 team2 -t 4242 -c 11
    J'obtiens bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    map_x: 666
    map_y: 69
    port: 39115
    team 1: team1
    team 2: team2
    verbose: 1
    max_players: 11
    cronos: 4242
    Essayons en ne mettant qu'une seule option:
    On obtient bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    map_x: 0
    map_y: 0
    port: 0
    team 1: (null)
    team 2: (null)
    verbose: 0
    max_players: 0
    cronos: 4242
    Ton probleme n'est donc pas du cote de getopt().

  10. #10
    Invité
    Invité(e)
    Par défaut
    Avec ce meme code, essaye en appellant avec cette line
    $> ./toto -n team1 team2 -p 39115 -x 666 -y 69 -v -t 4242 -c 11

    Et tu verras que le resultat n'est pas bon !

    map_x: 0
    map_y: 0
    port: 0
    team 1: team1
    team 2: team2
    verbose: 0
    max_players: 0
    cronos: 0

  11. #11
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Je suis vraiment desole, mais chez moi (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) cela passe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    > toto -n team1 team2 -p 39115 -x 666 -y 69 -v -t 4242 -c 11
    map_x: 666
    map_y: 69
    port: 39115
    team 1: team1
    team 2: team2
    verbose: 1
    max_players: 11
    cronos: 4242
    C'est assez extraordinaire, on dirait bien que c'est ton getopt() qui ne fonctionne pas. Tu compiles avec des options exotiques?

  12. #12
    Invité
    Invité(e)
    Par défaut
    J'utilise ca dans mon Makefile :

    CFLAGS = -Wall -g3 -pedantic -ansi

    Sinon je taff avec :
    gcc version 3.3.3 (NetBSD nb3 20040520)

  13. #13
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    D'apres mon man 3 getopt(), cette fonction retourne -1 apres avoir termine, et non EOF comme tu l'utilises. Sur ma machine EOF etant egal a -1, cela n'entraine pas d'erreur, mais cela peut poser probleme sur la tienne. Sinon, je suis a cours d'idee...

  14. #14
    Invité
    Invité(e)
    Par défaut
    EOF est egal a -1 dans mon systeme aussi.

    La je suis paume -_-

  15. #15
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par NaeiKinDus
    malloc: Cannot allocate memory
    Ah! Enfin quelque-chose. Comme quoi il faut toujours verifier le retour de malloc(). Comme tu utilises une fonction non standard (xmalloc), je ne peux pas t'aider, mais il faut que tu creuses la dedans...

    Edit: Oups, tu as edite ton post on dirait. Plus d'erreur de malloc()?

  16. #16
    Invité
    Invité(e)
    Par défaut
    En fait, une erreur normale : mon malloc (xmalloc est un malloc qui verifie les valeurs de retour) se basait sur les valeurs recuperees... getopt ne pouvant rien recuperer (vu l'etonnant probleme avec les equipes), le malloc ne marchait pas ! Va mallocer un truc avec -132434687 ^_^
    Donc pas lie... donc je suis toujours perdu

  17. #17
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Oui, c'est vraiment etrange. As-tu la possibilite d'essayer sur une autre machine? Egalement, mets un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%s\n", optarg);
    dans la boucle while(), pour faire si getopt se plaint de quelque-chose...

  18. #18
    Invité
    Invité(e)
    Par défaut
    Resultat avec le printf et un passage "normal" d'arguments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    39115
    69
    69
    (null)
    100
    12
    lol
    Ce qui me semble parfaitement normal...

    Le meme avec les equipes en seconde position donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    39115
    lol
    malloc: cannot allocate memory
    Le malloc est normal car il est fait sur les options que getopt ne recupere pas...


    Et c'est comme ca sur toutes les machines de mon ecole
    Et je ne me sens vraiment pas la force de corriger tout mon code pour le faire compiler sous Sun ou autre pour le moment

  19. #19
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Si j'ai bien compris, meme le code que j'ai donne ci-dessus ne fonctionne pas chez toi, alors qu'il passe nickel ici dans tous les cas ? (il est assez facile de le tester sous Sun, celui-la). Dans ce cas, je seche completement. Avec un peu de chance quelqu'un aura une idee brillante (c'est peut-etre un truc idiot que l'on n'a pas vu...).

  20. #20
    Invité
    Invité(e)
    Par défaut
    Aussi bien sous Sun que sous NetBSD, il ne passe pas... je suis vraiment etonne !
    Ou sinon peut etre que c'est une configuration commune a mon ecole qui est en carton...?

Discussions similaires

  1. trier un HasMap par ses valeurs.
    Par techz dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 20/08/2009, 18h58
  2. Réponses: 4
    Dernier message: 05/06/2009, 10h40
  3. Réponses: 2
    Dernier message: 01/05/2009, 09h59
  4. [PHP 5.0] Tri/Affichage d'un tableau à partir d'une de ses valeurs
    Par Wearmoi dans le forum Langage
    Réponses: 1
    Dernier message: 31/03/2009, 16h34
  5. DataTable et ses valeurs
    Par gabdeschenes dans le forum ASP.NET
    Réponses: 3
    Dernier message: 25/03/2009, 15h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo