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
%lfpermitido enprintf7.19.6.1 La función
fprintf7 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
fscanf11 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