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 :

Passer un nombre inconnu de paramètres à une fonction


Sujet :

C

  1. #1
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut Passer un nombre inconnu de paramètres à une fonction
    Bonjour à tous.
    J'ai une fonction recevant un nombre inconnu de paramètres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void iso_printf(const char* string, ...);
    J'aimerais que cette fonction iso_printf() repasse tous ces paramètes à sprintf();

    Exemples (histoire d'ête compris)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    iso_printf("kikoolol %d", 12.3); // La fonction passera "kikoolol %d" et 12.3 à sprintf()
    iso_printf("kikoolol %c%i", 'E', 87); // La fonction passera "kikoolol %c%i", 'E' et 87 à sprintf()
    Et cela dynamiquement.

    Pouvez-vous m'aider à faire cela ?
    -- Yankel Scialom

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par prgasp77
    Bonjour à tous.
    J'ai une fonction recevant un nombre inconnu de paramètres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void iso_printf(const char* string, ...);
    J'aimerais que cette fonction iso_printf() repasse tous ces paramètes à sprintf();
    À sprintf, c'est pas possible mais il y a une fonction vsprintf() à laquelle c'est possible d'envoyer des arguments d'une fonction vararg. C'est d'ailleurs une bonne idée de faire une telle fonction quand on défini des fonctions varargs. Example d'utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
         void
         eprintf (const char *template, ...)
         {
           va_list ap;
           va_start (ap, template);
           vfprintf (stderr, template, ap);
           va_end (ap);
         }
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est pourquoi je conseille, si tu fais une fonction à nombre indéterminé d'arguments, de toujours la faire en va_list, et d'ajouter la version "..." comme un simple wrapper vers la version va_list...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Génial je te remercie !!!
    Alors voila le ce à quoi ton aide m'a servi : une fonction identique à printf() qui affiche correctement les caractères accentués dans une console.
    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
    void iso_printf(const char *sTemplate, ...)
    { //inclure <stdio.h>, <windows.h> et <stdarg.h>
    	/*
    	 * Conversion du template
    	 ***************************/
    	char iso_sTemplate[sizeof(sTemplate)+1];
    	CharToOem(sTemplate, iso_sTemplate);
    	/*
    	 * Gestion des arguments
    	 ***************************/
    	va_list lArguments;
    	va_start(lArguments, sTemplate);
    	vfprintf (stderr, iso_sTemplate, lArguments); // affichage
    	va_end (lArguments);
    	return;
    }
    Mais problème ... si un caractère accentué est présent parmi les arguments (qui peuvent être de type char*), celui-ci n'est pas traduit.
    Une idée ?
    -- Yankel Scialom

  5. #5
    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 prgasp77
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void iso_printf(const char *sTemplate, ...)
    {
    	char iso_sTemplate[sizeof(sTemplate)+1];
    	CharToOem(sTemplate, iso_sTemplate);
    }
    Comportement indéfini. sizeof retourne la taille de l'objet. Ici, c'est un pointeur (quelques bytes). De toutes façon, ce n'est pas la bonne solution :
    Mais problème ... si un caractère accentué est présent parmi les arguments (qui peuvent être de type char*), celui-ci n'est pas traduit.
    Une idée ?
    vsprintf(), puis traduction. La difficulté est d'évaluer correctement la taille nécessaire. Dans le doute, allouer dynamiquement puis libérer un gros buffer genre 32k... Ca couvrira beaucoup de cas, avec un risque non nul de comportement indéfini.

    Il y a une solution plus sûre qui utilise fichier bidon ("/dev/null" ou "nul" selon le système) et la valeur de retour de vfprintf(), mais ce n'est pas portable.
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Puisque tu utilises les fonctions Windows, tu peux utiliser la fonction Microsoft pour connaître la taille nécessaire pour un sprintf() : _scprintf() fait la mesure.
    (En C99, il suffit de passer NULL à la fonction standard snprintf(), mais M$ se fiche du C99 et a préféré nous pondre ses sprintf_s() à la place... )

    Edit: Ah, je n'avais pas lu la fin du post d'Emmanuel. C'est la méthode la plus portable, à ceci près que le fichier bidon est "/dev/null" sous unixoïde et "NUL" sous DOS/Windows...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    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 Médinoc
    le fichier bidon est "/dev/null" sous unixoïde et "NUL" sous DOS/Windows...
    OK, corrigé...

    Merci.
    Pas de Wi-Fi à la maison : CPL

Discussions similaires

  1. Passer un bout de code html en paramètre d'une fonction javascript
    Par yoshimitsu dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 04/08/2011, 14h40
  2. Nombre inconnu de paramètres à passer en requête
    Par gabz57 dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 20/02/2011, 16h19
  3. [Debutant] Nombre inconnu d'attribut
    Par ekinox17 dans le forum Débuter
    Réponses: 4
    Dernier message: 20/02/2006, 21h48
  4. Réponses: 2
    Dernier message: 09/06/2005, 09h49
  5. Comment gérer un nombre inconnu d'objet ?
    Par Clad3 dans le forum C++
    Réponses: 28
    Dernier message: 12/03/2005, 11h55

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