Fonctions à arguments variables.

Comment faire des fonctions comme printf, qui prennent un nombre variable d'arguments.

stdarg.h

Voir version :

Pas de dépendances

Télécharger :

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void myprint(char* format,...)
{
    char temp[1000];
    va_list ap;
    va_start(ap, format);
    vsprintf(temp, format, ap);
    va_end(ap);
    printf(temp);
}

int* Remplit_tableint(int n,...)
{
    int* res=malloc(n*sizeof(int));
    va_list ap;
    int i;
    va_start(ap,n);
    for(i=0;i<n;i++)
        res[i]=va_arg(ap,int);
    va_end(ap);
    return res;
}

int main()
{
    int i = 0;
    int* table;
    myprint("erf %d arf %d urf %f pif\n",5,28,0.652);
    table = Remplit_tableint(5,12,45,i,56,74);
    for(i=0;i<5;i++)
        printf("%d\n",table[i]);
    free(table);
    return 0;

}



Commentaires


Voici stdarg : ça parmet de faire des fonctions a nombre de parametres variables (comme printf).

Premiere partie :  myprint.
Le but est de faire comme printf, mettre des parametres apres la chaine de format, de ranger le tout dans un buffer. 
(apres, on printf le buffer mais la n'est pas l'importance)

Regardez la déclaration de myprint :

void myprint(char* format,...)

Les ... veulent dire que je mettrais surement d'autres parametres derriere. ça compile ! Mais mettez bien 
#include <stdarg.h>

Dedans, je récupere une va_list que j'appelle ap;
cette va_list contient en fait la liste des chaines que j'ai ajouté a la place des ...

va_start(ap, format);
--> Commence l'analyse (pourquoi passer "format" ? -> peut etre parce que c'est le dernier parametre avant les ..., mais je ne sais pas bien)

vsprintf(temp, format, ap);

vsprintf marche tres simplement : vous lui donnez le buffer destination (temp) comme sprintf, la chaine de format, et la liste de type va_list.
ça remplit temp.
N'oubliez pas le 	va_end(ap); pour etre propre. 


Deuxieme utilisation : pour initialiser un tableau : c'est tres utile.
Vous allez me dire "on peut tres bien faire : int tab[] = {3,5,6,7};

oui, certes, mais regardez mieux comment je l'appelle : (5,12,45,i,56,74);
j'ai un "i" au milieu. Cela n'est pas possible avec int tab[] = {3,5,i,7};  --> syntax error

Remplit_tableint remplit n éléments (a préciser)
Regardez :   va_arg(ap,int);  qui retire un "int" de la liste ap.