Jaki jest właściwy specyfikator formatu double
w printf? Czy to %f
jest czy jest %lf
? Wierzę, że tak %f
, ale nie jestem pewien.
Próbka kodu
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
c
floating-point
printf
double
format-specifiers
Lampart
źródło
źródło
"%lf"
jest niezdefiniowany; w bibliotekach C99 i C11 jest zdefiniowany jako taki sam jak"%f"
.%lf
jest poprawnym specyfikatorem formatu dladouble
. Ale stało się tak w C99. Wcześniej trzeba było użyć%f
.Odpowiedzi:
"%f"
jest (lub przynajmniej jednym) poprawnym formatem dla podwójnego. Jest to nie dla formatufloat
, ponieważ jeśli spróbujesz przejśćfloat
doprintf
, to będzie promowany nadouble
zanimprintf
otrzyma go 1 ."%lf"
jest również akceptowalny w ramach obecnego standardu -l
określa się, że nie wywołuje żadnego efektu, jeśli następuje po nim specyfikatorf
konwersji (między innymi).Zauważ, że jest to jedno miejsce, w którym
printf
ciągi formatujące różnią się zasadniczo odscanf
(ifscanf
itp.) Ciągów formatujących. Jako wynik podajesz wartość , która będzie promowana odfloat
do,double
gdy zostanie przekazana jako parametr variadic. Dla wejścia jesteś przechodzącą wskaźnik , który nie jest promowane, więc trzeba powiedziećscanf
, czy chcesz czytaćfloat
lubdouble
, tak abyscanf
,%f
oznacza, że chcesz czytaćfloat
i%lf
oznacza, że chcesz czytaćdouble
(i za to, co wartolong double
użyć%Lf
dla jednegoprintf
lubscanf
).1. C99, §6.5.2.2 / 6: „Jeśli wyrażenie oznaczające wywoływaną funkcję ma typ, który nie zawiera prototypu, promocje na liczby całkowite są wykonywane dla każdego argumentu, a argumenty, które mają typ float, są podwyższane dwukrotnie. Są to tak zwane domyślne promocje argumentów. ” W C ++ sformułowanie jest nieco inne (np. Nie używa słowa „prototyp”), ale efekt jest taki sam: wszystkie parametry variadic podlegają domyślnej promocji, zanim zostaną odebrane przez funkcję.
źródło
g++
odrzuca%lf
podczas kompilacji z-Wall -Werror -pedantic
:error: ISO C++ does not support the ‘%lf’ gnu_printf format
l
było rozszerzeniem. Standardy C99 / 11 i C ++ 11 wymagają implementacji, aby na to pozwolić.scanf
robi Kupiędouble
s reprezentowane przez%lf
: narzeka, że oczekujefloat *
i okazałodouble *
się po prostu%f
.scanf
trwa odnośniki do miejsca przechowywania, co czyta, więc potrzeby , aby wiedzieć, jak duża przestrzeń jest spiczasty, na to, podczas gdyprintf
trwa same wartości i „promocji argumentów domyślnych” oznacza zarówno skończyć jakodouble
s, więcl
jest zasadniczo opcjonalne.Biorąc pod uwagę standard C99 (mianowicie szkic N1256 ), reguły zależą od rodzaju funkcji: fprintf (printf, sprintf, ...) lub scanf.
Oto wyodrębnione części:
Te same zasady określone dla
fprintf
ubiegaćprintf
,sprintf
a podobne funkcje.Krótko mówiąc,
fprintf
określono następujące specyfikatory i odpowiadające im typy:%f
-> podwójne%Lf
-> długi podwójny.a do
fscanf
tego jest:%f
-> pływak%lf
-> podwójne%Lf
-> długi podwójny.źródło
To może być
%f
,%g
lub%e
w zależności od tego, jak chcesz numer do sformatowania. Zobacz tutaj po więcej szczegółów.l
Modyfikator jest wymaganascanf
zdouble
, ale nieprintf
.źródło
l
modyfikator (małe litery) dotyczy typów całkowitych ( cplusplus.com/reference/clibrary/cstdio/printf ) iL
jest przeznaczony dla typów zmiennoprzecinkowych. DodatkowoL
modyfikator oczekuje, along double
nie zwykłegodouble
.l
nie jest wymaganeprintf
dladouble
.Format
%lf
jest idealnie poprawnymprintf
formatemdouble
dokładnie tak, jak go używałeś. W twoim kodzie nie ma nic złego.Format
%lf
wprintf
nie był wspierany w starych (pre-C99) wersji języka C, który stworzył „powierzchowne” niespójność pomiędzy formatem specyfikatorami nadouble
wprintf
iscanf
. Ta powierzchowna niespójność została naprawiona w C99.Nie są wymagane do korzystania
%lf
zdouble
wprintf
. Możesz również użyć%f
, jeśli tak wolisz (%lf
i%f
masz równoważne wprintf
). Ale we współczesnym C sensowne jest preferowanie używania%f
zfloat
,%lf
zdouble
i%Lf
zlong double
, konsekwentnie w obuprintf
iscanf
.źródło
scanf()
,"%f"
,"%lf"
dopasowywaniafloat *, double *
, a niefloat, double
jak sugeruje ostatniej linii.%Lf
(uwaga na kapitałL
) jest specyfikatorem formatu dla długich podwójnych .Dla zwykłego
doubles
, albo%e
,%E
,%f
,%g
lub%G
zrobi.źródło
%g
i%G
?