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 :

Liste variable...


Sujet :

C

  1. #1
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut Liste variable...
    Bonjour,

    j'ai créé une fonction avec une liste variable d'arguments. Dans cette fonction, je doit faire une allocation dynamique pour une chaine de caracteres, chaine qui est completée grace aux argument variables (comme le fait par exemple la fonction printf, fprintf, etc...).
    Comment je peut retrouver la taille totale que prennent les arguments variables completant cette chaine, en tenant compte qu'on ne connais pas leur type à l'avance ?
    Mon but est de trouver la taille totale de la chaine de caracteres finale pour faire une allocation qui tiens la route !


    Merci pour votre aide

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Bon la technique c'est bon, on me l'a donnée, elle fonctionne tres bien sauf pour le type char*, l'exemple testé de cette page: http://www.linux-kheops.com/doc/man/...g.3.html#sect3
    mis en pratique donne ceci:
    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
    #include <stdarg.h>
    #include <stdio.h>
     
    void 
    foo (char *fmt, ...)
    {
      va_list ap;
      int     d;
      char    c, *p, *s;
      va_start  (ap, fmt);
      while     (*fmt)
        switch  (*fmt ++) {
          case 's': /* chaîne */
            s = va_arg (ap, char *);
            printf ("chaine %s\n", s);
            break;
          case 'd':  /* entier */
            d = va_arg (ap, int);
            printf ("int %d\n", d);
            break;
          case 'c':    /* caractère */
            c = va_arg (ap, char);
            printf ("char %c\n", c);
            break;
        }
      va_end (ap);
    }
     
    int main(void)
    {
       char *s1 = "salut";
       char *s2 = "au revoir";
       foo("%s %s", s1, s2);
       return 0;
    }
    Ce qui foncitonne très bien, mais, quand je le met en pratique dans ma fonction, cela ne fonctionne plus:
    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
    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
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    gint gui_dialog_message (GtkWindow *p_parent,
                             GtkMessageType message_type,
                             GtkButtonsType buttons_type,
                             const gchar *p_message,
                             ...)
    {
       GtkWidget *p_dialog;
       gchar *p_msg = NULL;
       gchar *s;
       gint ret_val, i, verif;
       size_t len;
       va_list params;
     
     
       /* Recuperation de la liste variable. */
       va_start (params, p_message);
     
     
       i = 0;
       len = 0;
       verif = 0;
       while ((i < strlen (p_message)) || (p_message[i] != '\0'))
       {      
          if (verif != 0)
          {
             verif = 0;
     
             switch (p_message[i])
             {            
                case 's':
                {
                   s = va_arg (params, gchar *);
                   printf ("%s\n", s);                  /* ---> A partir de la ca deconne !! */
                   len += strlen (s);
                }
                break;
     
                case 'd':
                {
                   len += sizeof (va_arg (params, gint));
                }
                break;
     
                case 'c':
                {
                   len++;
                }
                break;
             }
          }
          else if (p_message[i] == '%')
          {
             verif = 1;
          }
     
          i++;
       }
       len += strlen (p_message);
       fprintf (stdout, "len = %d\n", len);
     
     
       /* Allocation d'un espace pour contenir la chaine finale qui sera ensuite
          transmie en argument a la fonction de creation de la boite de message
          de GTK. */
       p_msg = g_malloc (len + 1);
       if (p_msg == NULL)
       {
          perror ("Memory allocation error of pointer \"p_msg\"");
          fprintf (stderr, "Error : %d\n", errno);
     
          exit (1);
       }
     
     
       /* Impression de la chaine finale. */
       vsprintf (p_msg, p_message, params);
     
     
       /* Creation de la boite de message. */
       p_dialog = gtk_message_dialog_new (
                      p_parent,
                      GTK_DIALOG_MODAL,
                      message_type,
                      buttons_type,
                      p_msg);
     
     
       /* Lancement de la boite de message. */
       ret_val = gtk_dialog_run (GTK_DIALOG (p_dialog));
     
     
       /* Suppresion de la boite de message. */
       gtk_widget_destroy (p_dialog);
     
     
       /* Liberation de la memoire et fin de la liste variable. */
       g_free (p_msg);
       p_msg = NULL;
       va_end (params);
     
     
       return ret_val;
    }
    Appel 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
             gchar *nom = "CSoldier";
             gint ret;
             gint i;
     
     
             i = 2;
     
             ret = gui_dialog_message (
                      GTK_WINDOW (p_app->p_window),
                      GTK_MESSAGE_QUESTION,
                      GTK_BUTTONS_YES_NO,
                      "Test n°%d d'une boite de message par:\n%s.",
                      i, nom);
    Moi je ne vois pas le problème, et ca fait deja un ptit bout de temps que j'essaie de le trouver !

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Bon, vraiment personne ne trouve l'erreur ? Moi je sais toujours pas d'où ca viens

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par CSoldier
    Bon, vraiment personne ne trouve l'erreur ? Moi je sais toujours pas d'où ca viens
    Au lieu de réinventer la roue, pourquoi tu n'utilises pas vsprintf() pour récupérer les paramètres variables ? Il sont expansés directement comme il faut dans une chaine, et il n'y a rien à décoder.

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Je connais vsprintf, je l'utilise meme dans le code mais il faut bien que j'alloue un espace memoire pour pouvoir stocker la chaine générée par vsprintf non ?

    Additif: Bon, pour le moment je stock la chaine créé par vsprintf dans un tableau de char tout simplement avec une taille prédéfinie, faut juste pas depasser cette limite et tout va bien.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par CSoldier
    Je connais vsprintf, je l'utilise meme dans le code mais il faut bien que j'alloue un espace memoire pour pouvoir stocker la chaine générée par vsprintf non ?

    Additif: Bon, pour le moment je stock la chaine créé par vsprintf dans un tableau de char tout simplement avec une taille prédéfinie, faut juste pas depasser cette limite et tout va bien.
    vsnprintf () en C99.
    Et puis il y a toujours l'astuce bien connue du *fprintf() vers "nul" ou "dev/nul" selon le système, qui retourne le nombre de caractères de la chaine sans créer de fichier...

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Citation Envoyé par CSoldier
    Je connais vsprintf, je l'utilise meme dans le code mais il faut bien que j'alloue un espace memoire pour pouvoir stocker la chaine générée par vsprintf non ?

    Additif: Bon, pour le moment je stock la chaine créé par vsprintf dans un tableau de char tout simplement avec une taille prédéfinie, faut juste pas depasser cette limite et tout va bien.
    vsnprintf () en C99.
    Et puis il y a toujours l'astuce bien connue du *fprintf() vers "nul" ou "dev/nul" selon le système, qui retourne le nombre de caractères de la chaine sans créer de fichier...
    Je connaissais pas cette astuce tiens

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 11/09/2007, 12h16
  2. ComboBox et largeur de liste variable
    Par davels dans le forum Delphi
    Réponses: 7
    Dernier message: 10/10/2006, 14h44
  3. Réponses: 10
    Dernier message: 20/03/2006, 16h15
  4. Réponses: 1
    Dernier message: 20/07/2005, 09h13
  5. [Merise] liste variable de propriétés
    Par Oberown dans le forum Schéma
    Réponses: 10
    Dernier message: 31/08/2004, 15h36

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