Correct Formatbezeichner für Doppel in printf
-
27-09-2019 - |
Frage
Was ist die richtige Formatangabe für double
in printf? Ist es %f
oder ist es %lf
? Ich glaube, es ist %f
, aber ich bin nicht sicher.
Codebeispiel
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
Lösung
"%f"
ist (oder zumindest ein) richtige Format für ein Doppelzimmer. Es is kein Format für eine float
, denn wenn man eine float
zu printf
passieren versuchen, es zu double
gefördert werden, bevor printf
es erhält 1 . "%lf"
ist auch akzeptabel, unter dem aktuellen Standard -. die l
als wirkungslos wird angegeben, wenn die f
Konvertierungsspezifizierer gefolgt (unter anderem)
Beachten Sie, dass dies ist ein Ort, dass printf
Formatstrings im Wesentlichen von scanf
unterscheiden (und fscanf
, etc.) Format-Strings. Für die Ausgabe Sie vorbei ein Wert , die von float
zu double
gefördert werden, wenn sie als variadische Parameter übergeben. Für die Eingabe Sie vorbei ein Zeiger , die nicht gefördert wird, so dass Sie scanf
sagen, ob Sie eine float
oder eine double
lesen wollen, so für scanf
, %f
Mittel Sie eine float
lesen möchten und %lf
Mittel Sie eine double
lesen (und für das, was es wert ist, für eine long double
, verwenden Sie %Lf
für beide printf
oder scanf
).
1. C99, §6.5.2.2 / 6: „Wenn der Ausdruck, der die genannte Funktion eine Art bezeichnet hat, die nicht einen Prototyp umfassen, sind die ganzzahligen Promotions auf jedes Argument durchgeführt und Argumente, die Typ float haben gefördert zu verdoppeln. diese sind die Standardargument Aktionen genannt.“ In C ++ ist die Formulierung etwas anders (zum Beispiel ist es nicht das Wort „Prototyp“), aber der Effekt ist das gleiche: alle variadische Parameter unterziehen Standardaktionen, bevor sie durch die Funktion empfangen ist.
Andere Tipps
In Anbetracht der C99 Standard (nämlich die N1256 Entwurf) hängen die Regeln für die Art-Funktion: fprintf (printf, sprintf, ...) oder scanf
.Hier werden relevante Teile extrahieren:
Vorwort
Diese zweite Ausgabe ersetzt die erste Ausgabe, ISO / IEC 9899: 1990, in der geänderten Fassung und korrigiert durch ISO / IEC 9899 / COR 1: 1994, ISO / IEC 9899 / AMD1: 1995 und ISO / IEC 9899 / COR 2 : 1996. Wesentliche Änderungen von der vorherigen Ausgabe sind:
%lf
Konvertierungsspezifizierer inprintf
erlaubt7.19.6.1 Die
fprintf
Funktion7 Die Länge Modifikatoren und deren Bedeutung sind:
l (ell) Gibt an, dass (...) hat keine Auswirkung auf einen Anschluss an eine, A, E, E, F, F, G, oder G Konvertierungsspezifizierer.
L Gibt an, dass ein folgenden a, A, E, E, F, F, G, oder G Konvertierungsspezifizierer auf ein langen Doppel Argument gilt.
Die gleichen Regeln für fprintf
angegeben gelten für printf
, sprintf
und ähnliche Funktionen.
7.19.6.2 Die
fscanf
Funktion11 Die Länge Modifikatoren und deren Bedeutung sind:
l (ell) Gibt an, dass (...), daß ein folgenden a, A, E, E, F, F, G, oder G Konvertierungsspezifizierer gilt für ein Argument mit Typ-Zeiger auf verdoppeln;
L Gibt an, dass ein Anschluss an eine, A, E, E, F, F, G, oder G Umwandlung Spezifizierer gilt für ein Argument vom Typ Zeiger auf long double.
12 Die Konvertierungsspezifizierer und ihre Bedeutung: a, e, f, g Spiele eine gegebenenfalls signierte Gleitkommazahl, (...)
14 Die Konvertierungsspezifizierer A, E, F, G und X gelten auch und verhalten sich gleich wie bzw. a, e, f, g und x.
Die lange Geschichte kurz, für fprintf
folgende Planer und entsprechende Typen angegeben werden:
-
%f
-> double -
%Lf
. -> long double
und für fscanf
es ist:
-
%f
-> float -
%lf
-> double -
%Lf
. -> long double
Es kann %f
, %g
oder %e
sein, je nachdem, wie Sie wollen, dass die Zahl formatiert werden. Finden Sie unter hier für weitere Details. Der l
Modifikator wird in scanf
mit double
erforderlich, aber nicht in printf
.
Das richtige printf
Format für double
ist %lf
, genau so, wie man es benutzt. Es ist nichts falsch mit Ihrem Code.
Format %lf
in printf
wurde in alten (pre-C99) Versionen von C-Sprache nicht unterstützt, die oberflächlich "Inkonsistenz" geschaffen zwischen Formatbezeichner für double
in printf
und scanf
. Die oberflächliche Inkonsistenz wurde in C99 festgelegt.
So in der modernen C macht es durchaus Sinn zu bevorzugen %f
mit float
zu verwenden, %lf
mit double
und %Lf
mit long double
sowohl konsequent in printf
und scanf
.
%Lf
(beachten Sie die Hauptstadt L
) ist der Formatspezifizierer < a href = "http://en.wikipedia.org/wiki/Long_double" rel = "noreferrer"> long double .
Für Ebene doubles
entweder %e
, %E
, %f
, %g
oder %G
tun wird.
Für Doppel können Sie einfach %lf
verwenden, oder Sie können alle folgenden gemäß Ihren Wünschen verwenden
%e
oder %E
für Werte in Exponentialformat
%g
oder %G
für entweder normal oder Exponentialnotation, je nachdem, was besser geeignet für seine Größe ist.
Lesen Sie mehr auf hier Liste der alle Formatbezeichner in C