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 :

var_args vides ?


Sujet :

C

  1. #1
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut var_args vides ?
    Salut,

    Je me demandais si il était possible de connaitre le nombre d'arguments d'une liste d'arguments variables ou bien de savoir si il ya au moins un argument.
    Le tout en pouvant appeler vsnprintf() par la suite.

    Mon probleme c'est que que je devrais pas appeler vsnprintf mais plutot strncpy si ce que je passe en parametre est une chaine n'ayant pas besoin d'être formattée. Surtout si ladite chaine contient un malencontreux %

    Solutions
    1) savoir si il ya des arguments dans la liste si oui => vsnprintf
    2) appeler ma_fonction("%s", "lachaine deja formattée et pouvant contenir des %")
    3) ajouter un parametre à ma_fonction pour savoir si faut formatter ou pas
    4) creer une ma_fonction_sans_formattage

    J'aimerais eviter les solutions 2, 3 et 4

  2. #2
    Membre chevronné Avatar de Jack_serious
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 350
    Par défaut
    Je ne pense pas.

    C'est le probleme des varargs...

    Il faut systematiquement prevoir un moyen de faire connaitre a la fonction appelee le nombre d'arguments qu'elle va recevoir.

    Soit on lui passe ce nombre en argument (une espece de argc), soit un nombre de symboles dans une chaine (printf()), etc.

    Il n'existe pas de moyen de connaitre le nombre d'arguments passes en parametre.

    Dans le cas ou on essaie de recuperer un parametre de trop avec la macro va_arg, le comportement est indefini.

    va_arg

    [...]

    If there is no next argument, [...] random
    errors will occur.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Gruik
    Je me demandais si il était possible de connaitre le nombre d'arguments d'une liste d'arguments variables ou bien de savoir si il ya au moins un argument. <...>
    Je ne comprends pas très bien où est le problème. La norme exige que le premier paramètre soit formel. L'usage veut qu'il fournisse un moyen d'analyser les autres paramètres (chaine avec formatteurs 'à-la-sprintf()', chaine 'maison', nombre de variables... peu importe).

    Si tu veux passer les paramètres à vsnprintf(), le choix du format est fixé : sprintf().

    Il n'y a donc rien à faire de plus. vnsprintf() va se débrouiller et retourner le compte rendu qui va bien.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Le problème, "si j'ai bien tout compris"(c), c'est que Gruik veut prendre l'interface à l'envers:
    "S'il n'y a pas de varargs, on ignore tous les formatteurs possibles"
    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.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Médinoc
    Le problème, "si j'ai bien tout compris"(c), c'est que Gruik veut prendre l'interface à l'envers:
    "S'il n'y a pas de varargs, on ignore tous les formatteurs possibles"
    Bah, erreur de codage... Ca ne devrait même pas compiler...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce n'est pas encore le moment de dire ça: Gruik demande comment faire une telle fonction: Il ne peut donc pas encore avoir commencé à coder...
    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
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Médinoc
    Ce n'est pas encore le moment de dire ça: Gruik demande comment faire une telle fonction: Il ne peut donc pas encore avoir commencé à coder...
    Je parle de l'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ma_variadic ("%s %d", "xxx");
    ma_variadic ("%s %d", 2);

  8. #8
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Non, à l'appel ça donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ma_fonction("pouet pouet %d - %s", entier, chaine);
    ma_fonction("chaine qui n'a pas besoin d'être formattée à 100% !");

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par Gruik
    Je me demandais si il était possible de connaitre le nombre d'arguments d'une liste d'arguments variables ou bien de savoir si il ya au moins un argument.
    Oui : http://www.developpez.net/forums/sho...47&postcount=6
    Mais je n'ai pas trouvé le moyen de coller ça dans une macro, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define macro(...) foo (PP_NARG_(__VA_ARGS__), __VA_ARGS__)
    Ne marchai pas si mes souvenirs sont exactes

  10. #10
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Hello,

    Citation Envoyé par Gruik
    Salut,

    Je me demandais si il était possible de connaitre le nombre d'arguments d'une liste d'arguments variables ou bien de savoir si il ya au moins un argument.
    Le tout en pouvant appeler vsnprintf() par la suite.
    Une fonction variadique "connait toujours" le nombre d'arguments quelle va devoir traiter, mais c'est de la responsabilité du programmeur, mais elle n'a aucun moyen en interne pour déterminer le nombre d'arguments. Quand tu spécifies un format à printf(),
    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d %s", n, str);
    printf() est au courant qu'il y a 2 arguments, donc elle va faire appel 2 fois à va_arg() avec les types qui vont bien suivant la spécification de format. Il est donc clair que spécifier 3 arguments dans la spécification de format et donner seulement 2 variables à formater va produire un comportement indéfini.


    Citation Envoyé par Gruik
    Mon probleme c'est que que je devrais pas appeler vsnprintf mais plutot strncpy si ce que je passe en parametre est une chaine n'ayant pas besoin d'être formattée. Surtout si ladite chaine contient un malencontreux %

    Solutions
    1) savoir si il ya des arguments dans la liste si oui => vsnprintf
    2) appeler ma_fonction("%s", "lachaine deja formattée et pouvant contenir des %")
    3) ajouter un parametre à ma_fonction pour savoir si faut formatter ou pas
    4) creer une ma_fonction_sans_formattage

    J'aimerais eviter les solutions 2, 3 et 4

    Une solution, faire ta propre fonction wrapper (que j'appelle vf() ) également variadique, qui reprend toutes les spécificateurs de formatage de *printf() (Bon courage ) et auxquels tu en rajoutes un perso non déjà réservé (exple : %K ) qui te permettra de dire à ta fonction variadique vf() qu'il s'agit d'une variable à ne pas formater et à ne pas passer à snprintf() (En effet, cette variable "sera référencée" par le va_list de vf(), et le va_list ne pourra pas être transmis tel quel à vsnprintf() ).

    Pour être plus explicite, ça donnerait en utilisation un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char chaineToBeFmt[] = "hello intrus";
    char chaineNotToBeFmt[] = "world";
    int unEntier;
    [...]
    vf("%5.5s %K %d", chaineToBeFmt, chaineNotToBeFmt, unEntier);
    A l'intérieur de vf(), tu scannes la chaine de format et tu utilises ce qu'il faut de stdarg.h pour récupérer les arguments. Pas simple si tu veux traiter tout ce qu'est capable de faire printf(), car c'est bel et bien un printf() qu'il faut refaire. En douce, à l'intérieur, tu as recontruit un format dans lequel tu as viré %K, tu ne prends que chaineToBeFmt et unEntier, tu donnes le tout à manger par exemple à snprintf(), et tu fais autre chose avec la variable qui correspondait au %K.

    A+

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Gruik
    Non, à l'appel ça donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ma_fonction("chaine qui n'a pas besoin d'être formattée à 100% !");
    Ca, c'est interdit."%" n'est pas un formatteur valide. C'est "%%"

    Si tu veux faire ça, il faut obligatoirement faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ma_fonction ("%s", "chaine qui n'a pas besoin d'être formattée à 100% !");
    Pas le choix.

    Ou alors, il faut définir un format propriétaire, mais tu ne pourras plus utiliser vsprintf().

  12. #12
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Re,

    Citation Envoyé par Gruik
    Non, à l'appel ça donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ma_fonction("pouet pouet %d - %s", entier, chaine);
    ma_fonction("chaine qui n'a pas besoin d'être formattée à 100% !");
    Ha , plus simple, on comprend mieux !

    En fait la chaine que tu passes à ma_fonction correspond dans tous les cas au format (ou faire en sorte que). Par rapport à ce que je raconte dans mon msg précédent, dans ce cas, il ne te reste qu'à parser la chaine de format pour savoir si il ya effectivement une conversion formatée à faire ou pas, et si oui, tu balances ton va_list à vsnprintf(). Ici par exemple, même si il y a % dans la chaine, il n'y a aucun spécificateur de format, donc tu ne fais pas le vsnprintf() avec.
    C'est plus simple, mais c'est déjà du boulot de parser correctement la chaine de format.

    A+

  13. #13
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Et si tu comptais le nombre de % hors ceux précédés d'un '\' ou d'un autre '%' ?

    En fait c'est un peu usine à gaz, rien que pour prendre en compte le cas "unique" ou il n'y a pas de formattage à faire; autant banir ce cas, et toujours considéré qu'il y a un formattage; Enfin je trouve ça plus simple

  14. #14
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Okay merci pour vos réponses

    J'avais effectivement pensé à analyser la chaine de format voir si il yavait un element de formattage valide, mais c'est compliqué et chuis pas sur de pouvoir assurer tous les cas.
    Pis il yaurait toujours des cas bizarres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf ("j'ai mangé 50%de bananes en plus");
    Où le %d est valide mais on ne voulait pas formatter

    Sympa la macro, mais ça serait un peu le binz à mettre en place dans mon cas (et on est pas en C99 pour l'instant)

    Non, on va faire en sorte d'utiliser "%s"

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

Discussions similaires

  1. Fonction vide
    Par vagabon dans le forum Autres éditeurs
    Réponses: 9
    Dernier message: 29/07/2003, 18h23
  2. [CR9] Bug avec les champs à valeur vide ?
    Par Djob dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 15/07/2003, 21h21
  3. [DOM] Balise vide...
    Par carlierd dans le forum Format d'échange (XML, JSON...)
    Réponses: 7
    Dernier message: 02/05/2003, 18h28
  4. [] Datagrid vide après modification des propriétés
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/09/2002, 16h37
  5. [CR] Avoir seulement une page blanche qd la base est vide???
    Par littleChick dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 13/08/2002, 18h26

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