Qual é o especificador de formato correto para double
no printf? É %f
ou é %lf
? Eu acredito que é %f
, mas não tenho certeza.
Amostra de código
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
c
floating-point
printf
double
format-specifiers
Leopardo
fonte
fonte
"%lf"
é indefinido; nas bibliotecas C99 e C11, é definido como o mesmo que"%f"
.%lf
é o especificador de formato correto paradouble
. Mas ficou assim em C99. Antes disso, era preciso usar%f
.Respostas:
"%f"
é o (ou pelo menos um) formato correto para um duplo. Não é nenhum formato para umfloat
, porque se você tentar passar umfloat
paraprintf
, vai ser promovido adouble
antes deprintf
recebe-lo 1 ."%lf"
também é aceitável sob o padrão atual - elel
é especificado como não tendo efeito se seguido pelof
especificador de conversão (entre outros).Observe que este é um local em que as
printf
strings de formato diferem substancialmente das strings de formatoscanf
(efscanf
etc.). Para saída, você está transmitindo um valor , que será promovido defloat
paradouble
quando transmitido como um parâmetro variável. Para entrada, você está passando um ponteiro , que não é promovido; portanto, você precisa informarscanf
se deseja ler umfloat
ou adouble
, portantoscanf
,%f
significa que você deseja ler umfloat
e%lf
significa que você deseja ler umdouble
(e, pelo que é vale a pena, para along double
, você usa%Lf
paraprintf
ouscanf
).1. C99, §6.5.2.2 / 6: "Se a expressão que denota a função chamada tiver um tipo que não inclua um protótipo, as promoções inteiras serão realizadas em cada argumento e os argumentos que possuem o tipo float serão promovidos para dobrar. Eles são chamados de promoções de argumento padrão ". Em C ++, o texto é um pouco diferente (por exemplo, não usa a palavra "protótipo"), mas o efeito é o mesmo: todos os parâmetros variáveis sofrem promoções padrão antes de serem recebidos pela função.
fonte
g++
rejeita%lf
ao compilar com-Wall -Werror -pedantic
:error: ISO C++ does not support the ‘%lf’ gnu_printf format
l
era uma extensão. Os padrões C99 / 11 e C ++ 11 requerem a implementação para permitir isso.scanf
faz faltadouble
s representados por%lf
: ele reclama que esperavafloat *
e encontroudouble *
com apenas%f
.scanf
leva ponteiros para onde armazenar o que ele lê, então necessidades saber quão grande é o espaço que está sendo apontado pelo é, enquantoprintf
leva os próprios valores, e "promoções de argumento padrão" significam ambos acabam comodouble
s, de modo que ol
é essencialmente opcional.Dado o padrão C99 (ou seja, o rascunho N1256 ), as regras dependem do tipo de função: fprintf (printf, sprintf, ...) ou scanf.
Aqui estão as partes relevantes extraídas:
As mesmas regras especificadas para
fprintf
solicitarprintf
,sprintf
e funções similares.A história longa, para
fprintf
os seguintes especificadores e tipos correspondentes são especificados:%f
-> duplo%Lf
-> long double.e por
fscanf
isso é:%f
-> flutuar%lf
-> duplo%Lf
-> long double.fonte
Pode ser
%f
,%g
ou%e
dependendo de como você deseja que o número seja formatado. Veja aqui para mais detalhes. Ol
modificador é necessáriascanf
comdouble
, mas não emprintf
.fonte
l
modificador (minúsculo) é para tipos inteiros ( cplusplus.com/reference/clibrary/cstdio/printf ) eL
para tipos de ponto flutuante. Além disso, oL
modificador espera along double
, não uma planíciedouble
.l
não é necessáriaprintf
paradouble
.Formato
%lf
é umprintf
formato perfeitamente correto paradouble
, exatamente como você o usou. Não há nada errado com o seu código.O formato
%lf
inprintf
não era suportado nas versões antigas (anteriores à C99) da linguagem C, que criavam "inconsistência" superficial entre os especificadores de formato paradouble
inprintf
escanf
. Essa inconsistência superficial foi corrigida em C99.Você não é obrigado a usar
%lf
comdouble
noprintf
. Você também pode usar%f
, se preferir (%lf
e%f
é equivalente aprintf
). Mas no C moderno, faz todo o sentido preferir usar%f
comfloat
,%lf
comdouble
e%Lf
comlong double
, consistentemente em ambosprintf
escanf
.fonte
scanf()
,"%f"
,"%lf"
corresponder a umfloat *, double *
, nãofloat, double
como implica a última linha.%Lf
(observe a capitalL
) é o especificador de formato para duplas longas .Para simples
doubles
, seja%e
,%E
,%f
,%g
ou%G
vai fazer.fonte
%g
e%G
?