sintaxis - Corregir especificador de formato para doble en printf
sintaxis de printf y scanf (6)
¿Cuál es el especificador de formato correcto para double
en 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?
}
Dado el estándar C99 (es decir, el borrador N1256 ), las reglas dependen del tipo de función: fprintf (printf, sprintf, ...) o scanf.
Aquí están las partes relevantes extraídas:
Prefacio
Esta segunda edición cancela y reemplaza la primera edición, ISO / IEC 9899: 1990, modificada y corregida por ISO / IEC 9899 / COR1: 1994, ISO / IEC 9899 / AMD1: 1995, e ISO / IEC 9899 / COR2: 1996. Los principales cambios de la edición anterior incluyen:
- Especificador de conversión
%lf
permitido enprintf
7.19.6.1 La función
fprintf
7 Los modificadores de longitud y sus significados son:
l (ell) Especifica que (...) no tiene efecto en los siguientes especificadores de conversión a, A, e, E, f, F, g o G.
L Especifica que el siguiente especificador de conversión a, A, e, E, f, F, g o G se aplica a un argumento doble largo.
Las mismas reglas especificadas para fprintf
aplican a printf
, sprintf
y funciones similares.
7.19.6.2 La función
fscanf
11 Los modificadores de longitud y sus significados son:
l (ell) Especifica que (...) el siguiente especificador de conversión a, A, e, E, f, F, g o G se aplica a un argumento con puntero de tipo para duplicar;
L Especifica que un especificador de conversión siguiente a, A, e, E, f, F, g o G se aplica a un argumento con puntero de tipo a doble largo.
12 Los especificadores de conversión y sus significados son: a, e, f, g Coincide con un número de punto flotante firmado opcionalmente, (...)
14 Los especificadores de conversión A, E, F, G y X también son válidos y se comportan igual que, respectivamente, a, e, f, g y x.
La historia corta, para fprintf
especifican los siguientes especificadores y los tipos correspondientes:
-
%f
-> doble -
%Lf
-> doble largo.
y para fscanf
es:
-
%f
-> flotar -
%lf
-> doble -
%Lf
-> doble largo.
El formato de printf
correcto para el double
es %lf
, exactamente como lo usó. No hay nada malo con tu código.
El formato %lf
en printf
no era compatible con versiones antiguas (anteriores a C99) del lenguaje C, lo que creaba una "inconsistencia" superficial entre los especificadores de formato para double
en printf
y scanf
. Esa inconsistencia superficial se ha corregido en C99.
Así que en C moderno tiene mucho sentido preferir usar %f
con float
, %lf
con double
y %Lf
con long double
consistente tanto en printf
como en scanf
.
Para el doble, simplemente puede usar %lf
o puede usar cualquiera de los siguientes según su preferencia
%e
o %E
para valores en formato exponencial
%g
o %G
para notación normal o exponencial, lo que sea más apropiado para su magnitud.
Lea más en aquí Lista de todos los especificadores de formato en C
Puede ser %f
, %g
%e
dependiendo de cómo desee que se formatee el número. Vea here para más detalles. El modificador l
se requiere en scanf
con double
, pero no en printf
.
"%f"
es el formato correcto (o al menos uno) para un doble. No hay formato para un float
, porque si intentas pasar un float
a printf
, se promoverá el double
antes de que printf
reciba 1 . "%lf"
también es aceptable según la norma actual: se especifica que l
no tiene efecto si está seguido por el especificador de conversión f
(entre otros).
Tenga en cuenta que este es un lugar donde las cadenas de formato printf
difieren sustancialmente de las cadenas de formato scanf
(y fscanf
, etc.). Para la salida, está pasando un valor , que se promoverá de float
a double
cuando se pase como un parámetro variadic. Para la entrada, está pasando un puntero , que no se promueve, por lo que tiene que decirle a scanf
si desea leer un float
o un double
, así que para scanf
, %f
significa que desea leer un float
y %lf
significa que desea para leer un double
(y, por lo que vale, para un long double
, usa %Lf
para printf
o scanf
).
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 el tipo float se promueven al doble. Estos se llaman las promociones de argumentos por defecto ". En C ++, la redacción es algo diferente (por ejemplo, no usa la palabra "prototipo") pero el efecto es el mismo: todos los parámetros variables se someten a promociones predeterminadas antes de que la función las reciba.
%Lf
(tenga en cuenta que la capital L
) es el cplusplus.com/reference/clibrary/cstdio/printf para los dobles largos .
Para los doubles
simples, ya sea %e
, %E
, %f
, %g
o %G