Какой правильный спецификатор формата для double
в printf? Это % f
или % lf
? Я считаю, что это % f
, но я не уверен.
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
"% f"
- это (или хотя бы один) правильный формат для двойного. Там нет формата для float
, потому что если вы попытаетесь передать float
на printf
, он будет повышен до double
до того, как printf
получит его 1 < / sup >. "% lf"
также приемлемо в соответствии с текущим стандартом - l
указывается как не имеющий эффекта, если за ним следует спецификатор преобразования f
(среди прочих).
Обратите внимание, что это одно место, где строки формата printf
существенно отличаются от scanf
(и fscanf
и т. Д.).) форматировать строки. Для вывода вы передаете значение , которое будет продвигаться от float
до double
при передаче в качестве вариационного параметра. Для ввода вы 'повторная передача указателя , который не продвигается, поэтому вы должны сказать scanf
, хотите ли вы прочитать float
или double
, так что для scanf
, % f
означает, что вы хотите прочитать float
, а % lf
означает, что вы хотите прочитать double
(а также, для чего это 'стоит, для "длинного дубля", Вы используете % Lf
для printf
или scanf
).
& Лт; sub >
Учитывая стандарт C99 (а именно, проект N1256 ), правила зависят от вид функции: fprintf (printf, sprintf, ...) или сканф.
Вот соответствующие детали извлечены:
Предисловие
Это второе издание отменяет и заменяет первое издание, ISO / IEC 9899: 1990, с поправками и исправлениями ISO / IEC 9899 / COR1: 1994, ISO / IEC 9899 / AMD1: 1995 и ISO / IEC 9899 / COR2: 1996. Основные изменения по сравнению с предыдущим изданием включают в себя:
% lf
спецификатор преобразования разрешен вprintf
7.19.6.1 Функция
fprintf
7 Модификаторы длины и их значения:
l * (ell) Указывает, что (...) не влияет на следующий спецификатор преобразования a, A, e, E, f, F, g или G.
L * Указывает, что следующий спецификатор преобразования a, A, e, E, f, F, g или G применяется к длинному двойному аргументу.
Те же правила, которые указаны для fprintf
, применяются для printf
, sprintf
и аналогичных функций.
7.19.6.2 Функция
fscanf
11 Модификаторы длины и их значения:
l * (ell) Указывает, что (...) что следующий спецификатор преобразования a, A, e, E, f, F, g или G применяется к аргументу с указателем типа на двойной ;
L * Указывает, что следующее преобразование a, A, e, E, f, F, g или G спецификатор применяется к аргументу с указателем типа на длинный двойной.
12 Спецификаторы преобразования и их значения: a, e, f, g Соответствует необязательно подписанному номеру с плавающей запятой (...)
14 Спецификаторы преобразования A, E, F, G и X также действительны и ведут себя так же, как, соответственно, a, e, f, g и x.
Короче говоря, для fprintf
указаны следующие спецификаторы и соответствующие типы:
% f
- > двойной% Lf
- > длинный двойной.и для fscanf
это:
% f
- > плавать% lf
- > двойной% Lf
- > длинный двойной.Это может быть % f
, % g
или % e
в зависимости от того, как вы хотите отформатировать число. Смотрите здесь для более подробной информации. Модификатор l
требуется в scanf
с double
, но не в printf
.
Правильный формат printf
для double
- это % lf
, точно так, как вы его использовали. В вашем коде нет ничего плохого.
Формат % lf
в printf
не поддерживался в старых (до C99) версиях языка C, что создавало поверхностную «несоответствие» между спецификаторами формата для double
в printf
и scanf
. Это поверхностное несоответствие было зафиксировано в C99.
Таким образом, в современном C имеет смысл предпочесть использовать % f
с float
, % lf
с double
и % Lf
с long double
последовательно как в printf
, так и в scanf
,.
% Lf
(обратите внимание на заглавную букву L
) - это спецификатор формата для длинных парных разрядов.
Для простых doubles
подойдет либо % e
, % E
, % f
, % g
или % G
.