Spécificateur de format Correct pour double en printf
Quel est le spécificateur de format correct pour double en printf? Est-ce %f ou %lf ? Je crois que c'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?
}
6 réponses
"%f" est le (ou au moins un) format correct pour un double. Il est pas de format pour un float , parce que si vous tentez de passer un float à printf , il sera promu à double avant printf le reçoit 1 . "%lf" est également acceptable dans la norme actuelle -- le l est spécifié comme n'ayant aucun effet s'il est suivi du f spécificateur de conversion (entre autres).
notez qu'il s'agit d'un endroit où les chaînes de format printf diffèrent considérablement de scanf (et fscanf , etc.) les chaînes de format. Pour la sortie, vous passez une valeur , qui sera promu de float à double lorsqu'il est passé comme un paramètre variadique. Pour l'entrée vous passez un pointeur , qui n'est pas promu, donc vous devez dire scanf si vous voulez lire un float ou un double , donc, pour scanf , %f signifie que vous voulez lire un float et %lf signifie que vous voulez lire un double (et, pour ce que ça vaut, pour un long double , vous utilisez %Lf , soit printf ou scanf ).
1. C99, §6.5.2.2 / 6: "Si l'expression qui dénote la fonction appelée a un type qui n'inclut pas un prototype, les promotions entières sont effectuées sur chaque argument, et les arguments qui ont le type float sont promus au double. Ceux-ci sont appelés les promotions d'argument par défaut."En C++ , le libellé est quelque peu différent (par exemple, il n'utilise pas le mot "prototype") mais l'effet est le même: tous les paramètres variadiques subissent des promotions par défaut avant d'être reçus par la fonction.
étant donné la norme c99 (à savoir, le projet N1256 ), les règles dépendent de 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/IEC 9899:1990, telle que modifiée et corrigée par ISO / IEC 9899 / COR1: 1994, ISO / IEC 9899/AMD1:1995, et ISO/IEC 9899 / COR2:1996. Les principaux changements par rapport à l'édition précédente comprennent:
%lfspécificateur de conversion autorisés dansprintf7.19.6.1 la
fprintffonction7 les modificateurs de longueur et leurs significations sont:
l (apl) Spécifie que les (...) n'a aucun effet sur un spécificateur de conversion A, A, e, E, F, g ou G.
l spécifie qu'un spécificateur de conversion A, A, e, F, F, g, ou G s'applique à un long argument double.
les mêmes règles que celles spécifiées pour fprintf s'appliquent pour printf , sprintf et fonctions similaires.
7.19.6.2 la fonction
fscanf151925092011 les modificateurs de longueur et leurs significations sont:
l (ell) spécifie que (...) qu'un spécificateur de conversion A, A, e, E, f, F, g ou G s'applique à un argument avec un pointeur de type à double;
L spécifie que la conversion suivante a, A, e, F, F, g, ou G specifier s'applique à un argument avec un pointeur de type à long double.
12 les spécificateurs de conversion et leurs significations sont: a, E, F, g correspond à un nombre flottant, (...)
14 les spécificateurs de conversion A, E, F, G et X sont également valides et se comportent comme, respectivement, A, e, f, g et X.
la longue histoire bref, pour fprintf , les spécificateurs et les types correspondants suivants sont spécifiés:
-
%f-> double -
%Lf- > long double.
et pour fscanf il est:
-
%f-> float -
%lf- > double -
%Lf- > long double.
le format correct printf pour double est %lf , exactement comme vous l'avez utilisé. Il n'y a rien de mal avec votre code.
Format %lf dans printf n'a pas été pris en charge dans l'ancien (pré-C99) versions du langage C, qui a créé superficielle "incohérence" entre les spécificateurs de format pour double dans printf et scanf . Cette incohérence superficielle a été corrigée en C99.
ainsi dans le C it moderne il est tout à fait logique de préférer utiliser %f avec float , %lf avec double et %Lf avec long double de façon cohérente dans les deux printf et scanf .
%Lf (notez la majuscule L ) est le spécificateur de format pour doubles longs .
pour plaine doubles , soit %e , %E , %f , %g ou %G fera l'affaire.
Pour double vous pouvez simplement utiliser %lf ou vous pouvez utiliser tout de suite selon votre préférence
%e ou %E pour les valeurs dans le format exponentiel
%g ou %G pour le mode normal ou en notation exponentielle, selon ce qui est le plus approprié pour son ampleur.
plus d'informations ici liste de tous les spécificateurs de Format C