it-swarm.com.de

Richtiger Formatbezeichner für double in printf

Was ist der richtige Formatbezeichner 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?
}
433
Leopard

"%f" ist das (oder mindestens ein) richtige Format für ein Double. Es gibt is kein Format für ein float, denn wenn Sie versuchen, ein float an printf zu übergeben, wird es zuvor zu double befördert printf empfängt es1. "%lf" ist nach dem aktuellen Standard ebenfalls zulässig - die Angabe l hat keine Auswirkung, wenn (unter anderem) die Angabe f folgt.

Beachten Sie, dass dies eine Stelle ist, an der sich Zeichenfolgen im Format printf erheblich von Zeichenfolgen im Format scanf (und fscanf usw.) unterscheiden. Für die Ausgabe übergeben Sie ein Wert, das von float zu double heraufgestuft wird, wenn es als variadischer Parameter übergeben wird. Für die Eingabe übergeben Sie ein Zeiger, das nicht hochgestuft wird. Sie müssen also scanf mitteilen, ob Sie ein float oder ein double lesen möchten. für scanf bedeutet %f, dass Sie einen float lesen möchten, und %lf bedeutet, dass Sie einen double lesen möchten (und, für was es sich lohnt, für a long double, verwenden Sie %Lf entweder für printf oder scanf).


1. C99, §6.5.2.2/6: "Wenn der Ausdruck, der die aufgerufene Funktion angibt, einen Typ hat, der keinen Prototyp enthält, werden die ganzzahligen Heraufstufungen für jedes Argument ausgeführt, und Argumente mit dem Typ float werden auf double heraufgestuft. Diese werden als Standardargument-Werbeaktionen bezeichnet. " In C++ ist der Wortlaut etwas anders (z. B. verwendet es nicht das Wort "prototype"), aber der Effekt ist der gleiche: Alle variadischen Parameter werden standardmäßigen Werbeaktionen unterzogen, bevor sie von der Funktion empfangen werden.

561
Jerry Coffin

Bei dem Standard C99 (dh dem Entwurf N1256 ) hängen die Regeln von der Funktionsart ab: fprintf (printf, sprintf, ...) oder scanf.

Hier sind relevante Teile extrahiert:

Vorwort

Diese zweite Ausgabe annulliert und ersetzt die erste Ausgabe, ISO/IEC 9899: 1990, geändert und korrigiert durch ISO/IEC 9899/COR1: 1994, ISO/IEC 9899/AMD1: 1995 und ISO/IEC 9899/COR2: 1996. Wichtige Änderungen gegenüber der vorherigen Ausgabe sind:

  • %lf Konvertierungsspezifizierer in printf zulässig

7.19.6.1 Die Funktion fprintf

7 Die Längenmodifikatoren und ihre Bedeutungen sind:

l (ell) Gibt an, dass (...) keine Auswirkung auf einen folgenden Konvertierungsspezifizierer hat: a, A, e, E, f, F, g oder G.

L Gibt an, dass ein folgender Konvertierungsbezeichner a, A, e, E, f, F, g oder G auf ein langes doppeltes Argument angewendet wird.

Für fprintf, printf und ähnliche Funktionen gelten die gleichen Regeln wie für sprintf.

7.19.6.2 Die Funktion fscanf

11 Die Längenmodifikatoren und ihre Bedeutungen sind:

l (ell) Gibt an, dass (...) ein nachfolgender Konvertierungsspezifizierer a, A, e, E, f, F, g oder G auf ein Argument mit Typ angewendet wird Zeiger auf double;

L Gibt an, dass ein nachfolgender Konvertierungsbezeichner a, A, e, E, f, F, g oder G auf ein Argument mit einem Typzeiger auf long double angewendet wird.

12 Die Umrechnungsangaben und ihre Bedeutungen sind: a, e, f, g Entspricht einer optional vorzeichenbehafteten Gleitkommazahl, (...)

14 Die Umrechnungsangaben A, E, F, G und X sind ebenfalls gültig und verhalten sich wie a, e, f, g und x.

Kurz gesagt, für fprintf werden die folgenden Bezeichner und entsprechenden Typen angegeben:

  • %f -> double
  • %Lf -> langes Doppel.

und für fscanf ist es:

  • %f -> float
  • %lf -> double
  • %Lf -> langes Doppel.
59
mloskot

Dies kann %f, %g oder %e sein, je nachdem, wie die Nummer formatiert werden soll. Siehe hier für weitere Details. Der Modifikator l ist in scanf mit double erforderlich, jedoch nicht in printf.

19
vitaut

Das richtige printf-Format für double ist %lf, genau wie Sie es verwendet haben. Es ist nichts falsch mit Ihrem Code.

Das Format %lf in printf wurde in alten (vor C99) Versionen der C-Sprache nicht unterstützt, was zu einer oberflächlichen "Inkonsistenz" zwischen den Formatspezifizierern für double in printf und scanf führte. Diese oberflächliche Inkonsistenz wurde in C99 behoben.

Daher ist es in modernem C durchaus sinnvoll, %f mit float, %lf mit double und %Lf mit long double sowohl in printf als auch in scanf zu verwenden.

10
AnT

%Lf (beachten Sie die Großbuchstaben L) ist Formatbezeichner für lange Doppelbuchstaben .

Für einfaches doubles ist entweder %e, %E, %f, %g oder %G ausreichend.

8