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 :

printf: format, flags, precision


Sujet :

C

  1. #1
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut printf: format, flags, precision
    Bonjour,

    dans une boucle, je lit des char. Normalement, ces chars devraient être des caractères imprimable, mais je m'aperçois que ce n'est pas le cas. Pour comprendre ce qui se passe, j'affiche donc le char (supposé imprimable) et le caractères hexa correspondant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char* buffer;
    /* ... code ...*/
    printf("char: [%c] [%02X]\n", buffer[0], buffer[0]);

    dans une boucle, voici ce qui s'affiche:
    char: [R] [52]
    char:[*] [2A]
    char: [U] [55]
    char: [ù] [FFFFFFF9]
    Et ma question c'est: pourquoi ça affiche [FFFFFFF9] au lieu de [F9]?

    J'ai mis un breakpoint pour voir ce qu'il y avait à l'adresse de buffer[0]:
    j'ai bien F9. devant il y a des 00 00 00 et derrière des cd cd cd cd.

    Je me suis dit que ça devait venir du fait que mes char sont des "signed char" et donc comme il y a un F, l'affichage remplit avec des F, mais si je met:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("char: [%c] [%02X]\n", buffer[0],(unsigned char*) buffer[0]);
    ça ne change rien.

    Quelqu'un a-t'il une explication?
    Et comment faire pour que ça affiche [F9] simplement?

    merci d'avance

  2. #2
    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
    Extension de signe.
    Code C incorrect : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0],(unsigned char*) buffer[0]);
    Problème de priorité: ici, j'ai l'impression que c'est buffer[0] que tu castes en pointeur (sans doute là encore après une extension de signe implicite).
    Deux "bonnes" façons sont disponibles:
    Code C correct : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /* Avec parenthèses pour ne plus avoir à se poser de questions */
    printf("char: [%c] [%02X]\n", buffer[0], (unsigned  char)(buffer[0]));
    Code C correct mais bizarre : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0], ((unsigned char*)buffer)[0]);
    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.

  3. #3
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut
    merci!, ça marche avec ta première bonne façon (surement aussi avec la deuxième, mais j'ai pas essayé)

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

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

    Citation Envoyé par Biosox
    merci!, ça marche avec ta première bonne façon (surement aussi avec la deuxième, mais j'ai pas essayé)
    Ne pas oublier que le spécificateur de conversion X de printf() attend un unsigned int. Comme le dit la norme, à partir du moment où on ne passe pas le type attendu, tout peut arriver. En l'occurence, tu donnais une valeur de pointeur sur unsigned char à manger à printf() que ce dernier a essayé de convertir en unsigned int. Et ce genre de conversion, c'est au mieux défini par l'implémentation, au pire un comportement défini si la valeur de pointeur ne peut être représentée dans le type entier cible.

    Pour être explicite, je réécrirais ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0],(unsigned int) buffer[0]);
    même si cela est correct aussi avec le cast en unsigned char .

    A+

  5. #5
    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
    Sauf que là, tu convertis directement le char en unsigned int, d'où extension de signe --> CQCÉ (Ce Qu'on Cherche à Éviter).
    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.

  6. #6
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par Foobar1329
    Ne pas oublier que le spécificateur de conversion X de printf() attend un unsigned int. Comme le dit la norme, à partir du moment où on ne passe pas le type attendu, tout peut arriver.
    En effet, il se passe n'importe quoi.
    A priori, mon buffer[0] pointe vers F9, F9 est un signed char.
    Il semblerai que lors de la conversion vers unsigned int, il a d'abort convertit F9 en FFFFFFF9...

    quoi qu'il en soit, j'ai finalement opté pour un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0], static_cast<unsigned int>(buffer[0]));
    et tout se passe comme je le souhaite (hormis que je reçois un F9 alors que je m'attendait à avoir une valeur < 7F, mais ça c'est une autre histoire

  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 Biosox
    quoi qu'il en soit, j'ai finalement opté pour un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0], static_cast<unsigned int>(buffer[0]));
    Pas du C.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0], (unsigned) (unsigned char) buffer[0]);
    Pas de Wi-Fi à la maison : CPL

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

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

    Citation Envoyé par Médinoc
    Sauf que là, tu convertis directement le char en unsigned int, d'où extension de signe --> CQCÉ (Ce Qu'on Cherche à Éviter).
    Oops, oui, la conversion en unsigned char est inévitable .

    La solution explicite est donnée par Emmanuel.

    A+

  9. #9
    Membre actif Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Pas du C.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("char: [%c] [%02X]\n", buffer[0], (unsigned) (unsigned char) buffer[0]);
    Effectivement c'est pas du C.
    arf je me mélange les pinceaux.

    Merci

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

Discussions similaires

  1. Format et Precision de nombre
    Par occor dans le forum MATLAB
    Réponses: 10
    Dernier message: 24/01/2008, 17h53
  2. printf: formater donnée!
    Par moon93 dans le forum C
    Réponses: 3
    Dernier message: 19/06/2006, 08h59
  3. probleme de format d`affichage(printf)
    Par smalto dans le forum C
    Réponses: 14
    Dernier message: 26/04/2006, 17h29
  4. Réponses: 1
    Dernier message: 30/03/2006, 13h03
  5. Réponses: 7
    Dernier message: 16/03/2006, 13h47

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