Correcte formaatspecificatie voor dubbel in printf

Wat is de juiste format specifier voor double in printf? Is het %f of is het %lf? Ik geloof dat het %f is, maar ik weet het niet zeker.

Code voorbeeld

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}
Oplossing

"%f" is het (of ten minste één) correcte formaat voor een double. Er is geen formaat voor een float, want als je probeert een float aan printf door te geven, wordt het gepromoveerd tot double voordat printf het ontvangt1. "%lf" is ook acceptabel onder de huidige standaard -- de l is gespecificeerd als geen effect hebbend indien gevolgd door de f conversie specificier (onder andere).

Merk op dat dit een plaats is waar printf format strings aanzienlijk verschillen van scanf (en fscanf, enz.) format strings. Voor output geef je een waarde door, die wordt gepromoveerd van float naar double als het als een variadic parameter wordt doorgegeven. Voor invoer geef je een pointer door, die niet gepromoveerd wordt, dus je moet scanf vertellen of je een float of een double wilt lezen, dus voor scanf betekent %f dat je een float wilt lezen en %lf dat je een double wilt lezen (en, voor wat het waard is, voor een long double gebruik je %Lf voor ofwel printf of scanf).


  1. C99, §6.5.2.2/6: "Als de expressie die de aangeroepen functie aanduidt een type heeft dat geen prototype bevat, worden de integer promoties uitgevoerd op elk argument, en argumenten die het type float hebben worden gepromoveerd naar double. Dit worden de standaard argument promoties genoemd." In C++ is de formulering enigszins anders (b.v., het gebruikt niet het woord "prototype") maar het effect is hetzelfde: alle variadische parameters ondergaan standaard promoties voordat zij'door de functie worden ontvangen.
Commentaren (6)

Het kan %f, %g of %e zijn, afhankelijk van hoe je het getal geformatteerd wilt hebben. Zie hier voor meer details. De l modifier is vereist in scanf met double, maar niet in printf.

Commentaren (2)

%Lf (let op de hoofdletter L) is de formaatspecificatie voor lange dubbels.

Voor gewone dubbels is %e, %E, %f, %g of %G voldoende.

Commentaren (3)