Вопрос

Какой правильный спецификатор формата для 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. "%lf" также приемлемо по текущему стандарту - l указан как не имеющий эффекта, если следовать f спецификатор преобразования (среди прочего).

Обратите внимание, что это одно место, которое printf Формат строки существенно отличается от scanf (а также fscanf, и т. Д.) Формат строки. Для вывода вы проходите стоимость, который будет продвигаться из float к double При прохождении в виде вариационного параметра. Для ввода вы проходите указатель, который не продвигается, так что вы должны сказать scanf хотите ли вы прочитать float или а double, Таким образом, для scanf, %f означает, что вы хотите прочитать float а также %lf означает, что вы хотите прочитать double (и, за что это стоит, для long double, ты используешь %Lf для любого printf или scanf).


1. C99, §6.5.2.2 / 6: «Если выражение, которое обозначает вызываемую функцию, имеет тип, который не включает в себя прототип, целочисленные акции выполняются на каждом аргументе, а аргументы, которые имеют тип плавающей способности к двойным. Они называются аргументом по умолчанию. В C ++ формулировка несколько отличается (например, она не использует слово «прототип»), но эффект одинаково: все вариадические параметры подвергаются по умолчанию, прежде чем они получены функцией.

Другие советы

Учитывая C99. стандарт (а именно, N1256. Проект) правила зависят от вида функций: FPRINTF (printf, sprintf, ...) или scanf.

Вот актуальные детали, извлеченные:

Преступность

Это второе издание отменяет и заменяет первое издание, 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 Модификаторы длины и их значения:

летание (ELL) Указывает, что (...) не влияет на следующий спецификатор преобразования A, A, E, E, F, F, F, F, F, G или G.

Летание Указывает, что следующий спецификатор преобразования A, E, E, E, F, F, G или G применяется к длинному двойному аргументу.

Те же правила, указанные для fprintf подать заявку printf, sprintf и подобные функции.

7.19.6.2 fscanf функция

11 Модификаторы длины и их значения:

летание (ELL) Указывает, что (...), что следующее спецификатор преобразования A, A, E, E, F, F, F, G или G применяется к аргументу с указателем типа для двойного;

Летание Указывает, что следующий спецификатор преобразования A, E, 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 не был поддержан в старых (Pre-C99) версиях языка C, который создал поверхностное «несоответствие» между спецификаторами формата для double в printf а также scanf. Отказ Это поверхностное несоответствие было зафиксировано в C99.

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

%Lf (Обратите внимание на столицу L) это Формат спецификатора для длинные удваивания.

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

Для двойного вы можете просто использовать %lf или вы можете использовать любое из следующих согласно вашему предпочтению

%e или %E Для значений в экспоненциальном формате

%g или %G для нормальной или экспоненциальной записи, в зависимости от того, что больше подходит для его величины.

Читайте больше нас. Список дополнительный спецификатор формата в C

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top