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 :

utiliser des define dans le format d'un fprintf


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Par défaut utiliser des define dans le format d'un fprintf
    Bonjour,
    J'ai défini les define suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define taille_max_msg      1976
     
    #define taille_max_msg_03   1582
    Pour ne changer la taille d'un message qu'à un endroit.
    Avant nous avions le code suivant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fprintf(fic_messages, "%13s%02s%-1976s\n",
                    msg_ts.wmsg_ven_num, msg_ts.wmsg_msg_typ, msg_ts.wmsg_msg_msg);
    Que j'ai transformé ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fprintf(fic_messages, "%13s%02s%-taille_max_msgs\n",
                    msg_ts.wmsg_ven_num, msg_ts.wmsg_msg_typ, msg_ts.wmsg_msg_msg);
    Bien évidemment cela ne donne pas le même résultat, je devais dormir quand j'ai écrit ça.
    Maintenant la question est comment obtenir le même résultat, avec quelque chose d'élégant et de lisible
    J'ai pensé à ceci, mais je trouve cela, pas très lisible.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char format[100];
    strcpy(format,"%13s%02s%-");
    strcat(format,itoa(taille_max_msg));
    strcat(format,"s\n");
    fprintf(fic_messages, format,
                    msg_ts.wmsg_ven_num, msg_ts.wmsg_msg_typ, msg_ts.wmsg_msg_msg);
    Avez vous une autre idée?
    PS : Je sais que itoa n'est pas standard, mais il existe dans mon application.
    Cordialement
    soazig

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* creation du format d'affichage */
    char format[100];
    sprintf(format,"%13s%02s%-%ds\n", taille_max_msg);
     
    /* affichage */
    fprintf(fic_messages, format,
                    msg_ts.wmsg_ven_num, msg_ts.wmsg_msg_typ, msg_ts.wmsg_msg_msg);
    ?


    C'est a peine plus court, peut être un peu plus lisible mais de toute façon, tu avais la bonne approche
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Tu peux faire quelque chose comme ceci:

    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
    #define STR(x) STR__(x)
    #define STR__(x) #x
     
    #define TAILLE_MAX_MSG 20
     
    #include <stdio.h>
     
    int main(void)
    {
        char message[] = "message";
     
        printf("----%-"STR(TAILLE_MAX_MSG)"s-----\n", message);
     
        return 0;
    }
    Avec mes meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  4. #4
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Tu peux aussi utiliser *, ce qui donne en reprenant l'exemple de Thierry:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #define TAILLE_MAX_MSG 20
     
    #include <stdio.h>
     
    int main(void)
    {
        char message[] = "message";
     
        printf("----%-*s-----\n", TAILLE_MAX_MSG , message);
     
        return 0;
    }

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Par défaut
    Bonjour,
    J'ai essayé la solution de gl, et j'ai eu un plantage à l'execution.
    Une erreur inconnue s'est produite : [The server threw an exception.]

    D'un autre côté c'était la première fois que je compilais moi même ce programme.
    J'ai alors regardé mon livre de c "C: langage bibliothèque, applications" de Henri Garreta et je n'ai pas vu la syntaxe du *. Je ne l'ai pas trouvé dans msdn non plus.

    Je vais essayer la solution suivante issue de la propositon de ram-0000
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    /* creation du format d'affichage */
    char format[100];
    sprintf(format,"%s%ds\n","%13s%02s%-", taille_max_msg);
     
    /* affichage */
    fprintf(fic_messages, format,
                    msg_ts.wmsg_ven_num, msg_ts.wmsg_msg_typ, msg_ts.wmsg_msg_msg);
    Car la solution de ram-0000 risquerait d'attendre deux chaines de caractère avant la taille.

    Je ne comprend pas la solution de Thierry Chappuis
    PS : compilateur Microsoft Visual C++ 2005

    Merci à tous pour votre aide
    Soazig

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par soazig Voir le message
    Je ne comprend pas la solution de Thierry Chappuis
    Elle tire parti de la puissance du préprocesseur C (et C++).

    Le but est d'obtenir une chaine "%-25s" par exemple en ayant 25 sous forme de nombre.

    Il y a 2 macro qui sont définies STR et STR__ qui permettent de transformer un nombre sous forme de chaine de caractères et ainsi on peut laisser le compilateur concaténer toutes les chaine de caractères "%-", "25" et "s" qui une fois mise bout à bout font "%-25s"

    La macro STR__ transforme son paramètre en chaine de caractères (operateur # des macro)

    Au fait, pourquoi 2 macro STR et STR__, pourquoi ne pas le faire en une seule macro ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Au fait, pourquoi 2 macro STR et STR__, pourquoi ne pas le faire en une seule macro ?
    On peut le faire uniquement en passant directement la valeur à la macro. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define STR__(x) #x
    printf("----%-"STR__(20)"s-----\n", message);
    Mais cela ne présente aucun intérêt : autant mettre "20" directement. Et si on a plein de lignes printf comme celle-là, au lieu de les modifier une par une, c'est préférable de passer par une constante définie dans une macro (ici TAILLE_MAX_MSG). Et dans ce cas, on n'a pas d'autre choix que de transformer la valeur de cette macro en chaine en utilisant deux autres macro (ici STR et STR__) : STR aura comme argument TAILLE_MAX_MSG ; ceci sera transformé en . Et STR__ transformera 20 en "20".

    Si on n'utilise qu'une seule macro, un code tel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define STR__(x) #x
    printf("----%-"STR__(TAILLE_MAX_MSG)"s-----\n", message);
    donnera le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("----%-TAILLE_MAX_MSGs-----\n", message);
    (c'est le nom de la macro TAILLE_MAX_MSG qui sera concaténé et non sa valeur).

    Je reconnais que c'est parfois déroutant ce genre de choses.

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Elle tire parti de la puissance du préprocesseur C (et C++).

    Le but est d'obtenir une chaine "%-25s" par exemple en ayant 25 sous forme de nombre.

    Il y a 2 macro qui sont définies STR et STR__ qui permettent de transformer un nombre sous forme de chaine de caractères et ainsi on peut laisser le compilateur concaténer toutes les chaine de caractères "%-", "25" et "s" qui une fois mise bout à bout font "%-25s"

    La macro STR__ transforme son paramètre en chaine de caractères (operateur # des macro)

    Au fait, pourquoi 2 macro STR et STR__, pourquoi ne pas le faire en une seule macro ?
    A cause du fonctionnement du pré-processeur CPP. Tu peux voir la doc à ce sujet ici. Une seule macro transformerait STR(TAILLE_MAX_MSG) en "TAILLE_MAX_MSG", car le pré-processeur ne pré-scanne pas les arguments d'une macro lorsque cette dernière effectue une transformation en chaîne de caractères ou une concaténation. Or, ce n'est pas ce qu'on veut. La deuxième macro est nécessaire pour transformer TAILLE_MAX_MSG en la valeur de la constance qu'elle représente. Comme la première macro ne réalise pas de transformation en chaîne de caractère, l'argument est pré-scanné et la macro TAILLE_MAX_MSG est remplacée par sa valeur. Il y a ensuite une deuxième passe sur cette macro pour remplacer STR(25) par STR__(25). Puis, cette deuxième macro est remplacée par "25".

    En espérant que cela vous aide un peu à comprendre

    Avec mes meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par soazig Voir le message
    J'ai essayé la solution de gl, et j'ai eu un plantage à l'execution.
    Une erreur inconnue s'est produite : [The server threw an exception.]

    D'un autre côté c'était la première fois que je compilais moi même ce programme.
    J'ai alors regardé mon livre de c "C: langage bibliothèque, applications" de Henri Garreta et je n'ai pas vu la syntaxe du *. Je ne l'ai pas trouvé dans msdn non plus.
    Pourtant c'est standard (enfin au moins C99, je n'ai pas regardé en C90, mais si ma mémoire ne me joue pas des tours c'est OK) :

    Citation Envoyé par ISO/IEC 9899-1999
    As noted above, a field width, or precision, or both, may be indicated by an asterisk. In this case, an int argument supplies the field width or precision. The arguments specifying field width, or precision, or both, shall appear (in that order) before the argument (if any) to be converted. A negative field width argument is taken as a - flag followed by a positive field width. A neg ative precision argument is taken as if the precision were omitted.
    Tu n'aurais pas oublié de mettre la taille en paramètre par hasard ?

  10. #10
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par gl Voir le message
    Pourtant c'est standard (enfin au moins C99, je n'ai pas regardé en C90, mais si ma mémoire ne me joue pas des tours c'est OK)
    Je confirme (je préconise aussi cette solution), un extrait du K&R:
    B.1.2 Formatted Output
    ...
    Width or precision or both may be specified as *, in which case the value is computed by
    converting the next argument(s), which must be int.
    @soazig: L'erreur viens certainement de ton programme, as-tu compilé celui de gl ?

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Par défaut
    Bonjour,
    Désolée pour msdn j'ai dit une bêtise.
    le * est bien mentionné
    http://msdn.microsoft.com/en-us/libr...=VS.80%29.aspx

    Pour le livre de Garetta il date d'avant 99 (du temps de mes études, acheté probablement en 96 ou 97, je me fais vieille)
    J'avais peut-être dérapé lorsque j'ai fait mon test. Je garde cette idée pour une prochaine fois, car c'est bien cela que je cherchais.
    Le sprintf
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf(format,"%s%ds\n","%13s%02s%-", taille_max_msg);
    moins élégant fonctionne.
    Donc je vais désormais me pencher sur les problèmes d'algorithmiques de mon programme.
    Merci de votre aide.
    Soazig

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

Discussions similaires

  1. [JSP] Utilisation des Generics dans une scriptlet
    Par trochv dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 13/06/2006, 14h23
  2. utilisation des panel dans une fenetre Win32
    Par ksoft dans le forum MFC
    Réponses: 1
    Dernier message: 02/05/2006, 21h45
  3. [XSL] Utiliser des CSS dans un fichier XSL
    Par alainme dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 13/04/2005, 10h47
  4. [VB.NET] Utilisation des sessions dans Session_End ?
    Par San Soussy dans le forum ASP.NET
    Réponses: 2
    Dernier message: 02/02/2005, 16h40
  5. Utilisation des nombres dans Winsock2
    Par DeusXL dans le forum MFC
    Réponses: 14
    Dernier message: 01/12/2004, 17h36

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