¿Cuál es el especificador de formato correcto para double
printf? ¿Es %f
o es %lf
? Creo que es %f
, pero no estoy seguro.
Muestra 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
fuente
fuente
"%lf"
no está definido; en las bibliotecas C99 y C11 se define como igual que"%f"
.%lf
es el especificador de formato correcto paradouble
. Pero se hizo así en C99. Antes de eso tenía que usar%f
.Respuestas:
"%f"
es el formato correcto (o al menos uno) para un doble. No es ningún formato para unafloat
, ya que si se intenta pasar unafloat
aprintf
, que va a ser promovido adouble
antes deprintf
la recibe 1 ."%lf"
también es aceptable según el estándar actual:l
se especifica que no tiene efecto si es seguido por elf
especificador de conversión (entre otros).Tenga en cuenta que este es un lugar que
printf
las cadenas de formato difieren sustancialmente descanf
(efscanf
, etc.) las cadenas de formato. Para la salida, está pasando un valor , que se promocionará defloat
adouble
cuando se pasa como parámetro variadic. Para la entrada estás pasando un puntero , que no se promueve, por lo que tiene que decirscanf
si desea leer unfloat
o unadouble
, así que parascanf
,%f
medios que desea leer unafloat
y%lf
medios que desea leer unadouble
(y, por lo que es vale la pena, por unlong double
, que utiliza%Lf
para cualquieraprintf
oscanf
).1. C99, §6.5.2.2 / 6: "Si la expresión que denota la función llamada tiene un tipo que no incluye un prototipo, las promociones de enteros se realizan en cada argumento, y los argumentos que tienen tipo flotante se promueven a doble. Estos se denominan promociones de argumento predeterminadas ". En C ++, la redacción es algo diferente (p. Ej., No usa la palabra "prototipo") pero el efecto es el mismo: todos los parámetros variables se someten a promociones predeterminadas antes de ser recibidos por la función.
fuente
g++
rechaza%lf
al compilar con-Wall -Werror -pedantic
:error: ISO C++ does not support the ‘%lf’ gnu_printf format
l
era una extensión. Los estándares C99 / 11 y C ++ 11 requieren la implementación para permitirlo.scanf
hace faltadouble
s representada por%lf
: se queja de que se esperafloat *
y se encontródouble *
con sólo%f
.scanf
lleva los punteros a dónde almacenar lo que lee, por lo que necesita saber qué tan grande es el espacio al que se apunta, mientras queprintf
toma los valores en sí mismos y las "promociones de argumento predeterminadas" significan que ambos terminan comodouble
s, por lo quel
es esencialmente opcional.Dado el estándar C99 (es decir, el borrador N1256 ), las reglas dependen del tipo de función: fprintf (printf, sprintf, ...) o scanf.
Aquí se extraen las partes relevantes:
Las mismas reglas especificadas para
fprintf
solicitarprintf
,sprintf
y funciones similares.La larga historia corta, para
fprintf
los siguientes especificadores y tipos correspondientes se especifican:%f
-> doble%Lf
-> largo doble.y por
fscanf
eso es:%f
-> flotador%lf
-> doble%Lf
-> largo doble.fuente
Puede ser
%f
,%g
o%e
dependiendo de cómo desee que se formatee el número. Ver aquí para más detalles. Ell
modificador se requierescanf
condouble
, pero no conprintf
.fuente
l
modificador (en minúsculas) es para tipos enteros ( cplusplus.com/reference/clibrary/cstdio/printf ), yL
es para tipos de punto flotante. Además, elL
modificador espera unlong double
, no un planodouble
.l
no se requiereprintf
paradouble
.El formato
%lf
es unprintf
formato perfectamente correctodouble
, exactamente como lo usó. No hay nada malo con tu código.El formato
%lf
enprintf
no era compatible con las versiones antiguas (anteriores a C99) del lenguaje C, lo que creaba una "inconsistencia" superficial entre los especificadores de formato paradouble
inprintf
yscanf
. Esa inconsistencia superficial se ha solucionado en C99.No es obligatorio usarlo
%lf
condouble
inprintf
. También puede usar%f
, si así lo prefiere (%lf
y%f
son equivalentesprintf
). Pero en la C moderna tiene mucho sentido preferir usar%f
confloat
,%lf
condouble
y%Lf
conlong double
, consistentemente en ambosprintf
yscanf
.fuente
scanf()
,"%f"
,"%lf"
coincida con unafloat *, double *
, nofloat, double
como se deduce de la última línea.%Lf
(tenga en cuenta la capitalL
) es el especificador de formato para dobles largos .Para llano
doubles
, o bien%e
,%E
,%f
,%g
o%G
lo hará.fuente
%g
y%G
?