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 :

[Windows] sprintf et "numbered arguments"


Sujet :

C++

  1. #1
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut [Windows] sprintf et "numbered arguments"
    Bonjour à tous,

    je suis actuellement entrain d’internationaliser des applications et j'ai une petite question. Nous utilisons Visual Studio 2010. Il existe des messages avec des paramètres.
    exemple: Connexion de %s sur le port %d.

    J'ai vu qu'il existait dans la fonction printf la possibilité de spécifié la position de l'argument à utiliser en utilisant le caractère '$'. C'est appelé "numbered arguments". D'après ce que j'ai pu trouver, il semble que cela soit une extension POSIX.
    (http://pubs.opengroup.org/onlinepubs...ns/printf.html)
    J'ai essayer pour être sur mais Visual Studio ne supporte pas cette extension du C.

    Je voudrait savoir s'il existe une solution similaire sous windows ?
    Ou existe un compilateur sous windows qui supporte cette extension ?
    (MinGw ne le supporte pas déjà testé).

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Tu peux utiliser printf avec boost::bind et si je ne me trompe pas, il y a un équivalant à boost::bind dans la norme C++11.

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Pour utiliser des arguments positionnels en C++ sans tomber dans els défauts de printf (pas typesafe, pas extensible pour des types utilisateurs...), je te conseille de jeter un œil vers boost.format.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    J'ai regarder std::bind, cela ne correspond pas à mon besoin. En effet, il faudrait que je fasse un switch sur le identifiant de la langue ce qui me plaie vraiment moyen (voir pas du tout).

    L'objet boost::format par contre est très intéressant. Existe t'il en c++11 ?
    J'ai regarder mais pas encore trouver pour le moment.

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Non, boost.format n'a pas été inclus en C++11.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Peux-tu nous montrer exactement ce que tu cherches à faire et dans quel but?

  7. #7
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Pour donner un exemple concret de message que nous affichons :
    Français : Erreur %s sur le port COM%d
    Chinois simplifié : COM%d端口上发生%s错误

    Comme vous pouvez le voir les paramètres du format ne sont pas dans le même ordre. Ici, il ne s'agit que de deux paramètres mais on peut en avoir bien plus dans un ordre complètement aléatoire.

    Les arguments positionnés semble être une très bonne solution à ce problème.

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Dans ce cas là, pourquoi ne pas écrire :
    Erreur $1 sur le port COM$2

    Et remplacer la sous-chaîne "$1" par la bonne valeur?
    C'est tout à fait possible pour un std::string, il suffit de rechercher la sous-chaîne puis de remplacer cette sous-chaîne par une autre sous-chaîne.

  9. #9
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Là j'arrive pas a vous suivre. Je vois bien rechercher la chaîne $x de la ressource. Mais après je vois pas vraiment comment vous voulez faire ?

    Note: La fonction qui charge la ressource est appelée avec des paramètres variables ( void Display(ResId, ...); ).

  10. #10
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Chercher ta sous-chaîne : find_end
    Insérer ta valeur : std::string::replace

  11. #11
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Au risque de paraître bête, je vois toujours pas comment vous faites. En effet, j'aimerai ne pas changer le prototype de la fonction. J'ai vraiment du mal à comprendre comment vous voyez là chose sachant que je doit déclarer un va_list.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void DisplayV(int iResId, ...)
    {
      UStringRessource rstr(iResId);
      va_list param;
      va_start(param, iResId);
      ... // Je faisait wsprintf() ici
      va_end(param);
    }

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Je n'ai pas utilisé de va_list depuis un moment, mais il me semble qu'il faut mettre en place un système de boucle pour parser les arguments.
    Qu'est-ce qui t'empêche alors d'ajouter un compteur ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  13. #13
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Je n'ai pas utilisé de va_list depuis un moment, mais il me semble qu'il faut mettre en place un système de boucle pour parser les arguments.
    Qu'est-ce qui t'empêche alors d'ajouter un compteur ?
    C'est possible à condition de connaitre le type de chaque paramètre dans le va_list. Voir la macro va_arg.

    Finalement ça reviens à re-coder "printf()" ce qui n'est pas un mince à faire. C'est pour cette raison que je cherche une solution autre.

  14. #14
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Kalite Voir le message
    Au risque de paraître bête, je vois toujours pas comment vous faites. En effet, j'aimerai ne pas changer le prototype de la fonction. J'ai vraiment du mal à comprendre comment vous voyez là chose sachant que je doit déclarer un va_list.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void DisplayV(int iResId, ...)
    {
      UStringRessource rstr(iResId);
      va_list param;
      va_start(param, iResId);
      ... // Je faisait wsprintf() ici
      va_end(param);
    }
    Nope.

    Si tu utilise C++, il y a de bien meilleures façon de procéder (boost.format n'utilise pas de varargs, et fonctionne pourtant très bien : cf. l'explication donnée dans http://www.boost.org/doc/libs/1_51_0...oc/format.html).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  15. #15
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Je vais lire attentivement la documentation dès que possible. Merci pour l'info.

  16. #16
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Tel que je comprends format, tous les arguments sont finalement des string
    Ce qui est ce qui disait neckara plus haut, et tes vararg sont donc tous des const char*
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  17. #17
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Suite à la lecture de la documentation de boost::format(), j'ai pas vraiment le choix pour faire ce que souhaite.

    Il faut que supprime la fonction avec les var_arg et que je modifie mon objet UStringRessource pour qu'il reprenne la syntaxe de boost::format(). (Operateur %)

    Mon seul problème c'est les formateurs (exemple: %02d) que j'avais avec sprintf. Il vas falloir que je trouve un moyen de les remplacer.

    Note: Au final, ça vas ce rapprocher d'un codage de la fonction printf().

  18. #18
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Kalite Voir le message
    Suite à la lecture de la documentation de boost::format(), j'ai pas vraiment le choix pour faire ce que souhaite.

    Il faut que supprime la fonction avec les var_arg et que je modifie mon objet UStringRessource pour qu'il reprenne la syntaxe de boost::format(). (Operateur %)

    Mon seul problème c'est les formateurs (exemple: %02d) que j'avais avec sprintf. Il vas falloir que je trouve un moyen de les remplacer.

    Note: Au final, ça vas ce rapprocher d'un codage de la fonction printf().
    Oui, mais un codage typesafe, dans lequel tu n'as pas besoin de préciser le type des variables attendues parce que, miracle, ils sont découvert par le compilateur

    Du coup, tu n'a qu'à parser quelque chose du style %n. Si tu souhaite ajouter des éléments de formatage, je te conseille de les mettre entre deux séparateurs (par exemple: %4{02}). Ca va te simplifier le parsing, puisque tu sais que si il y a un { après le nombre (ou avant ; c'est toi qui voit), alors il y a un formatage à faire ; si tu ne peux pas faire de formatage sur cette sortie, alors tu peux ignorer jusqu'au } suivant.

    Sans ça, tu seras obligé de faire un parsing beaucoup plus compliqué, sans compter les cas tordus ou tu risque fort d'être incapable de décider de ce que tu dois faire.

    Bien évidemment, si tu avais accès aux variadic templates, c'eut-été encore mieux
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  19. #19
    Membre confirmé
    Avatar de Kalite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 310
    Points : 553
    Points
    553
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Bien évidemment, si tu avais accès aux variadic templates, c'eut-été encore mieux
    J'ai juste vue que cela existait mais j'ai pas encore utilisé le concept. A cause du compilateur qui ne les supporte pas et parce que je ne me suis pas encore vraiment penché sur le sujet.

    Merci à tous pour toutes ces infos.

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

Discussions similaires

  1. Quote et double quote
    Par aktos dans le forum Langage
    Réponses: 8
    Dernier message: 05/01/2007, 19h55

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