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 :

paramétrer une impression de double sur un printf


Sujet :

C

  1. #1
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut paramétrer une impression de double sur un printf
    Bonjour

    Je cherche à charger une chaine avec la valeur d'un double.
    Première tentative du débutant que je suis:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    F64Valeur = 0.00002369;
    sprintf(Ligne,"valeur = %lf\n",F64Valeur);
    et j'obtiens
    valeur = 0.000024
    il y a eu un arrondi au 6ieme chiffre significatif

    j'ai réussi à faire un peu mieux avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    F64Valeur = 0.00002369;
    sprintf(Ligne,"valeur = %0.15lf\n",F64Valeur);
    et j'obtiens
    valeur = 0.000023690000000
    Mais
    1) comment virer tous ces 0 à la fin qui pénalisent la lecture ?
    2) et si la valeur n'a pas 15 mais 16 chiffres significatifs, par exemple F64Valeur = 0.000000000000002369; ?

    Je n'ai pas réussi à trouver d'autres moyens de formater les %f, y en a t-il ?

    Merci

  2. #2
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 160
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    double essai=0.00002369;
    printf("double %.8f\n",essai);
    Va t'afficher avec 8 chiffres après la virgule. Par défaut, printf doit afficher 6 chiffres après la virgule et fait donc un arrondi.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu ne peux pas dire d'afficher autant de décimales que possibles, mais pas les 0 finaux.
    Par contre, tu peux modifier la string pour la raccourcir.

    Par exemple ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    F64Valeur = 0.00002369;
    sprintf(Ligne,"valeur = %0.15lf\n",F64Valeur);
     
    char* p = Ligne+27;
    while(p>Ligne && *p=='0') --p;
     
    if (*(p+1) == '0') *(p+1) = '\0';

  4. #4
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Bonjour

    merci pour vos réponses

    Là j'ai donné une valeur constant à F64valeur mais on est bien d'accord que ce n'est jamais la même valeur qui est à imprimer.

    Donc il faut que
    1) j'estime le nombre de chiffre significatifs que je peux avoir besoin dans le pire des cas dans mon appli, par exemple %0.25lf (soyons fou mais j'essaierai de l'être un peu moins)
    2) une fois le sprintf exécuté pour remplir "Ligne" je passe "Ligne" à la moulinette pour enlever les 0 en trop à la fin ?

    merci

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 746
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 746
    Par défaut
    En lisant la documentation sur le format printf, on s’aperçoit qu'il y a le format "%.*lf" avec lequel on peut spécifier la précision en paramètre.

    Donc avec une succession de multiplication de 10, on peut trouver la place du dernier chiffre

    Exemple non testé, non compilé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        unsigned char last_index = 0;
        double float_value = F64valeur;
        int last_decimal;
     
        for(unsigned char index = 0; index < XX; ++index) {
            float_value *= 10.0;
            last_decimal = ((int) float_value - (int) (((int) float_value) * 10));
     
            if (last_decimal != 0) { last_index = index ; }
        }
    Il faut regarder la norme pour remplacer XX

  6. #6
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 160
    Par défaut
    Je prendrais plutôt la proposition de leternel de modifier la chaine plutôt que de faire une boucle avec des multiplications.
    Donc il faut que
    1) j'estime le nombre de chiffre significatifs que je peux avoir besoin dans le pire des cas dans mon appli
    Pas besoin, tu utilises par exemple %.16f, puis tu vires les 0 excessifs de la chaine avec par exemple un strcspn
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  7. #7
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    Pas besoin, tu utilises par exemple %.16f, puis tu vires les 0 excessifs de la chaine avec par exemple un strcspn
    justement c'est le 0.16 qu'il faut que je détermine

    mon code sert à saisir des paramètres de fonctionnement dans un boitier électronique. si demain j'ai un paramètre =0.0000000000000000000012345 à saisir je suis balo avec 0.16. C'est cette limite qu'il faut que je détermine.
    A moins que l'on puisse mettre ce 0.16 en DEFINE genre
    auquel cas j'aurais juste un define à définir en fonction de l'application concernée mais je n'ai pas réussi à trouver si c'est possible d'utiliser des define ainsi.

    par ailleurs je découvre strcspn et je ne vois pas comment elle peut m'aider à retirer les 0 à la fin.


    Merci

  8. #8
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Citation Envoyé par petitours Voir le message
    [...]
    A moins que l'on puisse mettre ce 0.16 en DEFINE genre
    auquel cas j'aurais juste un define à définir en fonction de l'application concernée mais je n'ai pas réussi à trouver si c'est possible d'utiliser des define ainsi.
    [...]
    Bonjour,

    On peut.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    #define PRECISION(m,n) "%" #m "." #n "Lf"
    #define PRE_DEFAULT "%.12Lg"
     
    int main (void) {
      long double g=0.00001111;
     
      printf ("g = " PRECISION(1,5) "\n", g);
      printf ("g = " PRE_DEFAULT "\n", g);
     
      return 0;
    }
    Qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    g = 0.00001
    g = 1.111e-05
    La première macro n'est pas safe et ne doit être utilisée qu'avec des constantes littérales. La seconde ne pose pas de problèmes particuliers.

  9. #9
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    sinon, je ne sais plus les détails, mais il y a un format de notation scientifique, qui donnerait 1.2346E-17.
    regarde la documentation de *printf

    Autre chose, si tu donnes NULL=0 en chaine cible de sprintfsnprintf, la fonction te renvoie la taille qu'il faut allouer pour pouvoir contenir tout le texte. (Point à vérifier: avec le '\0'?)

    EDIT: en fait, ca n'est vrai que pour snprintf.

  10. #10
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Toujours à propos du define ... Il y a aussi la possibilité de donner la précision en paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
     
    int main (void) {
      long double g=0.0123456789L;
     
      for (int i=0;i<26;++i)
        printf ("précision : % 2d\tg=%.*Lf\n", i, i, g);
     
      return 0;
    }
    qui donne :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    précision :  0	g=0
    précision :  1	g=0.0
    précision :  2	g=0.01
    précision :  3	g=0.012
    précision :  4	g=0.0123
    précision :  5	g=0.01235
    précision :  6	g=0.012346
    précision :  7	g=0.0123457
    précision :  8	g=0.01234568
    précision :  9	g=0.012345679
    précision :  10	g=0.0123456789
    précision :  11	g=0.01234567890
    précision :  12	g=0.012345678900
    précision :  13	g=0.0123456789000
    précision :  14	g=0.01234567890000
    précision :  15	g=0.012345678900000
    précision :  16	g=0.0123456789000000
    précision :  17	g=0.01234567890000000
    précision :  18	g=0.012345678900000000
    précision :  19	g=0.0123456789000000000
    précision :  20	g=0.01234567890000000000
    précision :  21	g=0.012345678900000000000
    précision :  22	g=0.0123456788999999999997
    précision :  23	g=0.01234567889999999999974
    précision :  24	g=0.012345678899999999999743
    précision :  25	g=0.0123456788999999999997432

  11. #11
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Merci pour vos réponses

    Je teste différentes directions avec ce que vous me proposez

    petites questions pour comprendre
    1) dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long double g=0.0123456789L;
    il sert à quoi le "L" ?

    2) strcspn, comment peut elle m'aider à retirer les 0 en trop à la fin ? je ne vois pas le rapport

    3)
    Autre chose, si tu donnes NULL=0 en chaine cible de sprintf, la fonction te renvoie la taille qu'il faut allouer pour pouvoir contenir tout le texte. (Point à vérifier: avec le '\0'?)
    j'ai testé avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    status = sprintf(NULL,"%lf",F64valeur) ;
    (
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    status = sprintf(NULL=0,"%lf",F64valeur) ;
    ne compile pas) mais ça fait planter mon appli à l’exécution, genre ça va écrire à l'adresse 0 ?

    4)Aprés la question qui me vient est : cela mange il plus de ressource de faire la précision sur %.40lf plutôt qu'avec %.15lf ? par ce que sinon je mets 40, je vire les 0 en trop dans tous les cas et zou.

    Je parle de ressource parce que je suis sur un microcontrôleur là...CortexM0+ de ARM

    Merci

  12. #12
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Bon j'ai fait des tests avec 0.15 et 0.50 et en fait ca ne fait pas trembler mon petit cortexM0+.. alors je vais partir sur la solution où je sprintf avec une précision de 50 et après je repositionne la fin de chaine.

    Par contre j'ai beau le tourner dans tous les sens mon niveau en C ne me permet pas de comprendre ce code :
    Citation Envoyé par leternel Voir le message
    Tu ne peux pas dire d'afficher autant de décimales que possibles, mais pas les 0 finaux.
    Par contre, tu peux modifier la string pour la raccourcir.

    Par exemple ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    F64Valeur = 0.00002369;
    sprintf(Ligne,"valeur = %0.15lf\n",F64Valeur);
     
    char* p = Ligne+27;
    while(p>Ligne && *p=='0') --p;
     
    if (*(p+1) == '0') *(p+1) = '\0';
    Serait il possible de l'avoir en français pour que je puisse essayer de comprendre les syntaxes ?

    Merci

  13. #13
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Est ce que par hasard ca ne voudrait pas dire

    char* p = Ligne+27; => initialisation d'un pointeur à la fin de la chaine
    while(p>Ligne && *p=='0') --p; => en partant de la fin de la chaine et tant que l'on a un 0 on remonte la chaine

    if (*(p+1) == '0') *(p+1) = '\0'; => là je comprends toujours pas


    ne peut il pas être remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* p = Ligne + strlen(Ligne) -1
    ? parce que ce ne sera pas toujours 27 dans mon cas.

    Merci encore

  14. #14
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Citation Envoyé par petitours Voir le message
    Merci pour vos réponses

    Je teste différentes directions avec ce que vous me proposez

    petites questions pour comprendre
    1) dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long double g=0.0123456789L;
    il sert à quoi le "L" ?
    le L sert à indiquer au compilateur que la constante littérale est un long double.

    Citation Envoyé par petitours Voir le message
    2) strcspn, comment peut elle m'aider à retirer les 0 en trop à la fin ? je ne vois pas le rapport

    3)
    j'ai testé avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    status = sprintf(NULL,"%lf",F64valeur) ;
    (
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    status = sprintf(NULL=0,"%lf",F64valeur) ;
    ne compile pas) mais ça fait planter mon appli à l’exécution, genre ça va écrire à l'adresse 0 ?
    Il faut utiliser snprintf.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
     
    int main (void) {
      long double g=0.0123456789L;
     
      printf ("         11111111112222222222\n");
      printf ("12345678901234567890123456789\n");
      printf ("%.20Lf\n", g);
      printf ("%d\n", snprintf(NULL,0,"%.20Lf",g));
     
      return 0;
    }
    donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
             11111111112222222222
    12345678901234567890123456789
    0.01234567890000000000
    22
    La taille renvoyée par snprintf est la taille de la chaîne sans le 0 terminal.

    Citation Envoyé par petitours Voir le message
    4)Aprés la question qui me vient est : cela mange il plus de ressource de faire la précision sur %.40lf plutôt qu'avec %.15lf ? par ce que sinon je mets 40, je vire les 0 en trop dans tous les cas et zou.

    Je parle de ressource parce que je suis sur un microcontrôleur là...CortexM0+ de ARM

    Merci
    Plus ou moins de souvenir, un float contient environ 7 chiffres décimaux significatifs, un double environ 15 et un long double environ 20. Il est inutile de demander à les afficher avec une précision plus grande.

  15. #15
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Citation Envoyé par picodev Voir le message
    le L sert à indiquer au compilateur que la constante littérale est un long double.
    Il faut mettre ce genre de terminaison dans quels cas ? je n'ai jamais mis ça et je n'ai jamais eu de problèmes, c'est quoi le risque ?


    Citation Envoyé par picodev Voir le message
    Il faut utiliser snprintf.
    il faut l'utiliser pour avoir la longueur de la chaine ou pour virer les 0 de la fin ? je ne suis pas sur de comprendre la portée de la remarque.
    Citation Envoyé par picodev Voir le message
    La taille renvoyée par snprintf est la taille de la chaîne sans le 0 terminal.
    Ce n'est pas ce que fait strlen(Ligne) ? parce que si je pouvais éviter de charger mon code avec un autre fonction de lib ce serait bien, je n'ai pas une place infinie dans le µc...



    Citation Envoyé par picodev Voir le message
    Plus ou moins de souvenir, un float contient environ 7 chiffres décimaux significatifs, un double environ 15 et un long double environ 20. Il est inutile de demander à les afficher avec une précision plus grande.
    oui mais si les chiffres significatifs sont décalés après le zéro ça augmente le besoin en précision du sprinf, par exemple
    est moins exigent que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0.000000000000000000000000123456789
    Merci

  16. #16
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Citation Envoyé par petitours Voir le message
    Il faut mettre ce genre de terminaison dans quels cas ? je n'ai jamais mis ça et je n'ai jamais eu de problèmes, c'est quoi le risque ?
    Par défaut en C quand tu donnes une constante littérale le compilateur la convertit traite en double. Si tu utilises des long double cela permet de conserver plus de précision. Le code suivant te le montre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
     
    int main (void) {
      long double avecL=1.23456789012345678901L;
      long double sansL=1.23456789012345678901;
     
      printf("avecL=%.25Lf\n", avecL);
      printf("sansL=%.25Lf\n", sansL);
     
      return 0;
    }
    donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    avecL=1.2345678901234567889861130
    sansL=1.2345678901234566904321355
    Citation Envoyé par petitours Voir le message

    il faut l'utiliser pour avoir la longueur de la chaine ou pour virer les 0 de la fin ? je ne suis pas sur de comprendre la portée de la remarque.
    Ce n'est pas ce que fait strlen(Ligne) ? parce que si je pouvais éviter de charger mon code avec un autre fonction de lib ce serait bien, je n'ai pas une place infinie dans le µc...
    Si c'est ce que fera strlen(Ligne) après le sprintf. Utiliser la méthode du snprintf te permet de connaître la taille à allouer à Ligne avant le sprintf. Mais apparemment tu n'en as pas besoin.

    Citation Envoyé par petitours Voir le message

    oui mais si les chiffres significatifs sont décalés après le zéro ça augmente le besoin en précision du sprinf, par exemple
    est moins exigent que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    0.000000000000000000000000123456789
    Merci
    Utilise une notation scientifique pour l'affichage. Avec un le format %Lg, tu n'auras plus le problèmes des 0 à la fin et ce sera plus lisible. Il est plus facile de lire 1.23456789e-25 que 0.000000000000000000000000123456789. Enfin à mon avis.

  17. #17
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    pour répondre à la question sur status = sprintf(NULL=0,"%lf",F64valeur) ;.

    Attention, l'idée qui suit est de bonne volontée, mais ne fonctionne qu'avec snprintf. Avec sprintf, c'est faux


    Le bon usage serait proche du code suivant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* alloue de la mémoire, penser à utiliser free() */
    char* string_of(double valeur) {
        // calcul de la taille à écrire
        unsigned int taille = sprintf(NULL, "%lf", valeur);
        // allocation d'un buffer de cette taille
        char * p = malloc(taille*sizeof(char)); //la norme fixe sizeof(char) == 1, mais je le mets par principe
        // retour en cas d'erreur
        if (p==NULL) return NULL;
        // écriture
        sprintf(p,"%lf", valeur) ;
        return p;
    }
    La raison pour laquelle ca plante chez toi, c'est que le premier appel n'écrit pas, il compte uniquement.

  18. #18
    Membre Expert
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Par défaut
    Il vaut mieux utiliser snprintf plutôt que sprintf pour récupérer la taille car la norme garantit le résultat uniquement pour snprintf.

    Citation Envoyé par Norme C11 pour snprintf
    Description
    The snprintf function is equivalent to fprintf, except that the output is written into an array (specified by argument s) rather than to a stream. If n is zero, nothing is written, and s may be a null pointer. Otherwise, output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array. If copying takes place between objects that overlap, the behavior is undefined.

    Returns
    The snprintf function returns the number of characters that would have been written had n been sufficiently large, not counting the terminating null character, or a neg ative value if an encoding error occurred. Thus, the null-terminated output has been completely written if and only if the returned value is nonnegative and less than n.
    Citation Envoyé par Norme C11 pour sprintf
    Description
    The sprintf function is equivalent to fprintf, except that the output is written into an array (specified by the argument s) rather than to a stream. A null character is written at the end of the characters written; it is not counted as part of the returned value. If copying takes place between objects that overlap, the behavior is undefined.

    Returns
    The sprintf function returns the number of characters written in the array, not counting the terminating null character, or a neg ative value if an encoding error occurred.
    D'ailleurs, sous linux avec gcc5.1 et la glibc2.21 le petit programme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    #include <string.h>
     
    int main (void) {
      const char test[]="Ceci est un test";
     
      printf("avec strlen   : %d\n", strlen(test));
      printf("avec snprintf : %d\n", snprintf(NULL,0,test));
      printf("avec sprintf  : %d\n", sprintf(NULL,test));
     
      return 0;
    }
    plante sur le sprintf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    avec strlen   : 16
    avec snprintf : 16
    Segmentation fault (core dumped)

  19. #19
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    ok, donc, c'est snprintf qui a ce comportement.
    Je m'en souviendrai. Pardonnez mon erreur, je fais surtout du C++.

    De toute façon, je n'utilise personnellement jamais sprintf.

Discussions similaires

  1. Stopper une impression sur Windows NT Pro ?
    Par coralie26 dans le forum Windows Serveur
    Réponses: 2
    Dernier message: 29/09/2007, 17h32
  2. Impression d'étiquettes sur une Dymo LabelWriter 400
    Par robun dans le forum VBA Access
    Réponses: 3
    Dernier message: 29/08/2007, 07h43
  3. Réponses: 21
    Dernier message: 11/06/2007, 09h30
  4. Réponses: 2
    Dernier message: 22/01/2007, 20h06
  5. Parametrer le nombre d'index sur une table
    Par Invité dans le forum Access
    Réponses: 1
    Dernier message: 17/05/2006, 11h36

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