Правильный спецификатор формата для двойного в printf

Какой правильный спецификатор формата для double в printf? Это % f или % lf? Я считаю, что это % f, но я не уверен.

Образец кода

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}
Комментарии к вопросу (2)
Решение

"% f"- это (или хотя бы один) правильный формат для двойного. Там нет формата для float, потому что если вы попытаетесь передать float на printf, он будет повышен до double до того, как printf получит его 1 < / sup >. "% lf"также приемлемо в соответствии с текущим стандартом - l указывается как не имеющий эффекта, если за ним следует спецификатор преобразования f (среди прочих).

Обратите внимание, что это одно место, где строки формата printf существенно отличаются от scanffscanf и т. Д.).) форматировать строки. Для вывода вы передаете значение , которое будет продвигаться от float до double при передаче в качестве вариационного параметра. Для ввода вы 'повторная передача указателя , который не продвигается, поэтому вы должны сказать scanf, хотите ли вы прочитать float или double, так что для scanf, % f означает, что вы хотите прочитать float, а % lf означает, что вы хотите прочитать double (а также, для чего это 'стоит, для "длинного дубля", Вы используете % Lf для printf или scanf).


& Лт; sub >

  1. C99, & # 167; 6.5.2.2 / 6: «Если выражение, которое обозначает вызываемую функцию, имеет тип, который не включает прототип, целочисленные промо-акции выполняются для каждого аргумента, а аргументы, имеющие тип float, повышаются до двойной. Они называются акциями аргументов по умолчанию.«В C ++ формулировка несколько иная (например,., он не использует слово «прототип»), но эффект одинаков: все вариационные параметры проходят рекламные акции по умолчанию, прежде чем они будут получены функцией. & Лт; / sub >
Комментарии (6)

Учитывая стандарт 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 - > длинный двойной.
Комментарии (0)

Это может быть % f, % g или % e в зависимости от того, как вы хотите отформатировать число. Смотрите здесь для более подробной информации. Модификатор l требуется в scanf с double, но не в printf.

Комментарии (2)

Правильный формат printf для double - это % lf, точно так, как вы его использовали. В вашем коде нет ничего плохого.

Формат % lf в printf не поддерживался в старых (до C99) версиях языка C, что создавало поверхностную «несоответствие» между спецификаторами формата для double в printf и scanf. Это поверхностное несоответствие было зафиксировано в C99.

Таким образом, в современном C имеет смысл предпочесть использовать % f с float, % lf с double и % Lf с long double последовательно как в printf, так и в scanf ,.

Комментарии (0)

% Lf (обратите внимание на заглавную букву L) - это спецификатор формата для длинных парных разрядов.

Для простых doubles подойдет либо % e, % E, % f, % g или % G.

Комментарии (3)