tipos sintaxis salida para formatos formato especificadores datos c printf double format-specifiers

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 en printf

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.