Question

Quel est le spécificateur de format correct pour double à printf? Est-il ou est-il %f %lf? Je crois qu'il est %f, mais je ne suis pas sûr.

Exemple de code

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}
Était-ce utile?

La solution

"%f" est la (ou au moins une) format correct pour un double. Il pas de format pour un float, parce que si vous essayez de passer un float à printf, il sera promu double avant printf reçoit 1 . "%lf" est également acceptable selon la norme actuelle. - le l est spécifié comme sans effet si elle est suivie par le spécificateur de conversion de f (entre autres)

Notez que c'est un endroit que les chaînes de format printf diffèrent sensiblement des chaînes de format scanf (et fscanf, etc.). Pour la sortie, vous passez valeur , qui sera promu de float à double lorsqu'il est passé en tant que paramètre variadique. Pour l'entrée vous passez pointeur , qui n'est pas promu, vous devez dire scanf si vous voulez lire un float ou un double, donc pour scanf, des moyens de %f que vous voulez lire un float et des moyens de %lf vous voulez lire un double (et, pour ce que ça vaut, pour un long double, vous utilisez %Lf soit pour printf ou scanf).


1. C99, §6.5.2.2 / 6: « Si l'expression qui désigne la fonction appelée a un type qui ne comprend pas un prototype, les promotions entières sont effectuées sur chaque argument, et les arguments qui ont de type float sont promus à doubler. on les appelle les promotions d'argument par défaut « . En C ++ le libellé est quelque peu différente (par exemple, il n'utilise pas le mot « prototype »), mais l'effet est le même: tous les paramètres par défaut variadique subissent des promotions avant qu'ils ne soient reçus par la fonction.

Autres conseils

Compte tenu de la norme C99 (à savoir le N1256 projet) , les règles dépendent du la fonction type: fprintf (printf, sprintf, ...) ou scanf

.

Voici les parties pertinentes extraites:

  

Avant-propos

     

Cette deuxième édition annule et remplace la première édition, ISO / CEI 9899: 1990, tel que modifié et corrigé par l'ISO / CEI 9899 / COR1: 1994, ISO / CEI 9899 / AMD1: 1995 et ISO / CEI 9899 / COR2 : 1996.   Des changements majeurs de l'édition précédente comprennent:

     
      
  • spécificateur de conversion %lf autorisés dans printf
  •   
     

7.19.6.1 La fonction fprintf

     

7 Les modificateurs de longueur et leur signification sont:

     

l (ell) Indique que (...) n'a pas d'effet sur une suite a, A, e, e, f, f, g, ou spécificateur de conversion G.

     

L Spécifie qu'une suite a, A, E, E, F, F, G, ou G spécificateur de conversion applique à un long double argument.

Les mêmes règles spécifiées pour fprintf demander printf, sprintf et des fonctions similaires.

  

7.19.6.2 La fonction fscanf

     

11 Les modificateurs de longueur et leur signification sont:

     

l (ell) Indique que (...) qu'une suite a, A, e, e, f, f, g, ou spécificateur de conversion G applique à un argument de pointeur de type à doubler;

     

L Spécifie qu'une suite a, A, E, E, F, F, G, ou G conversion   spécificateur applique à un argument avec le pointeur de type à long double.

     

12 Les indicateurs de conversion et leurs significations sont:        a, e, f, g correspond à un nombre à virgule flottante éventuellement signé, (...)

     

14 Les indicateurs de conversion A, E, F, G et X sont également valables et comportent le même que, respectivement, a, e, f, g et x.

La longue histoire courte, pour fprintf les spécificateurs et les types correspondants sont spécifiés:

  • %f -> double
  • %Lf -.> Long double

et fscanf il est:

  • %f -> float
  • %lf -> double
  • %Lf -.> Long double

Il peut être %f, %g ou %e selon la façon dont vous voulez que le nombre à formater. Voir pour plus de détails. Le modificateur de l est nécessaire scanf avec double, mais pas dans printf.

Le format printf correct pour double est %lf, exactement comme vous l'avez utilisé. Il est faux de rien avec votre code.

Format %lf en printf n'a pas été pris en charge dans les anciennes versions (pré-C99) du langage C, qui a créé « incohérence » superficielle entre spécificateurs de format pour double dans printf et scanf. Cette incohérence superficielle a été corrigé dans C99.

Donc, en C moderne, il est parfaitement logique de préférer utiliser %f avec float, %lf avec double et %Lf avec long double toujours dans les deux printf et scanf.

%Lf (note la L du capital) est le spécificateur Format < a href = "http://en.wikipedia.org/wiki/Long_double" rel = "noreferrer"> longue double .

Pour doubles plaine, soit %e, %E, %f, %g ou %G fera.

Pour une double vous pouvez simplement utiliser %lf ou vous pouvez utiliser une des actions suivantes selon votre préférence

%e ou %E pour les valeurs en format exponentielle

%g ou %G soit pour la notation normale ou exponentielle, selon le plus approprié pour son ampleur.

En savoir plus sur ici Liste des tous les spécificateur de format en C

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top