Forum Programmation.c Fonctions variadiques imbriques

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
3
fév.
2016

Bonjour

Je bricole sur Arduino et ai les bases très basiques du C. (genre pas super à l'aise avec les pointeurs….)
J'ai besoin d'aide sur les fonctions variadiques imbriquées.

Dans mon code principal, j'appelle la fonction get_data_nesteed1 :

char url[20] = "";
int args_count = 0;
char str1[20] = "";
char str2[20] = "";
get_data_nesteed1( url , &args_count , str1 , str2 );

str1 et str2 sont les arguments variables, args_count est l'argument muet.

La fonction get_data_nesteed1 :

void get_data_nesteed1 ( char * purl , int * pargs_count , ... ) {
  va_list args;
  va_start( args, pargs_count );
  get_data_nesteed2( "ssss" , purl , pargs_count , args );
  va_end( args );
}

Cette fonction get_data_nesteed1 fait également appel à une fonction variadique get_data_nesteed2 en insérant des arguments.
L'argument muet change et est pfmt.
2 arguments variables ont été insérés. Ils y en a donc maintenant 4.

void get_data_nesteed2 ( const char * pfmt , ... ) {
  va_list args;
  va_start( args, pfmt );
  char *purl = va_arg( args, char * );
  strcpy( purl , "http://" );
  int *pargs_count = va_arg( args, int * );
  *pargs_count = strlen( pfmt );
  while (*pfmt != '\0') {
    char *s = va_arg( args, char * );
    strcpy( s , "Message" );
    ++pfmt;
  }
  va_end( args );
}

Une fois de retour dans ma fonction principale, j'obtiens :
url : Message
args_count : 4
str1 :
str2 : age
Donc, il y a un soucis….

Mais si j'appelle directement get_data_nesteed2, j'obtiens bien :
url : http://
args_count : 4
str1 : Message
str2 : Message

Ca ressemble beaucoup à l'exemple MyPrintf fourni ici :https://en.wikipedia.org/wiki/Stdarg.h#Example
Sauf que mon argument muet change et que des arguments "constants" deviennent des arguments variables.

Il y a une subtilité que je n'ai pas saisie…
Un volontaire pour m'expliquer ?

J'espère être clair….
Désolé pour le formatage de la fonction get_data_nesteed1, ça passe pas….

Merci.

David.

  • # ça marche pas tout a fait comme ça...

    Posté par  . Évalué à 2.

    Bonjour,

    En fait, si tu regarde le prototype de la fonction vsnprintf qui est utilisé dans l'exemple, tu verra que:

    • ça n'est pas: vsnprintf(str, size, format, ...)
    • c'est: vsnprintf(str, size, format, va_list ap)

    Donc dans ton cas, il ne faut pas définir:
    void get_data_nesteed2(const char *pfmt, ...)

    mais ceci:
    void get_data_nesteed2(const char *pfmt, va_list args)

    avec le code a simplifier en conséquence.

    Si tu ne peut pas changer le prototype de get_data_nested2, il va falloir penser le problème autrement, car il ne me semble pas possible de transmettre des variadics autrement que par l'intermédiaire du type va_list (si c'était possible, il n'y aurais pas 2 fonctions snprintf et vsnprintf pour faire la même chose)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.