printf에서 double에 대한 올바른 형식 지정자


480

doubleprintf에서 올바른 형식 지정자는 무엇입니까 ? 그것은인가 %f또는 그 것이다 %lf? 나는 그것을 믿지만 %f확실하지 않습니다.

코드 샘플

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}

19
C89 라이브러리에 갇혀 있으면 "%lf"정의되지 않습니다. C99 및 C11 라이브러리에서는와 동일하게 정의됩니다 "%f".
pmg

1
당신의 변형은 이제까지 정확합니다. %lf에 대한 올바른 형식 지정자입니다 double. 그러나 C99에서는 그렇게되었습니다. 그 전에 하나를 사용해야했습니다 %f.
AnT

답변:


624

"%f"double의 올바른 형식입니다. 이 없는 A의 어떤 형식은 float당신이를 통과하려고하면 때문에, floatprintf,이 승진 할 수 있습니다 double전에 printf그것을 받아 1 . "%lf"또한 현재 표준에서 허용됩니다.- 변환 지정자가 l뒤따를 경우 효과가없는 것으로 지정됩니다 f.

이것은 printf형식 문자열 이 형식 문자열과 scanf(및 fscanf등) 실질적으로 다른 곳입니다 . 출력의 경우, 당신은 전달하는 에서 추진됩니다 floatdouble가변 인자 매개 변수로 전달하는 경우입니다. 입력의 경우 당신은 전달하는 포인터 당신이 말할 필요가 있으므로, 승진되지 않으며, scanf당신이 읽을 것인지 float또는를 double정도, scanf, %f당신은을 읽을 수 수단 float%lf당신이를 읽으려는 수단을 double그것이 무엇을 위해, (그리고 가치는을 위해 long double, 당신은 사용 %Lf중 하나에 대한 printf또는 scanf).


1. C99, §6.5.2.2 / 6 : "호출 된 함수를 나타내는 표현식에 프로토 타입을 포함하지 않는 유형이있는 경우 각 인수에 대해 정수 승격이 수행되고 float 유형의 인수는 두 배로 승격됩니다. 이것을 기본 인수 프로모션이라고합니다. " C ++에서 표현은 약간 다릅니다 (예 : 단어 "prototype"을 사용하지 않음). 그러나 효과는 동일합니다. 모든 variadic 매개 변수는 함수가 받기 전에 기본 승격을받습니다.


8
다음 과 같이 컴파일 할 때 g++거부 %lf됩니다 -Wall -Werror -pedantic:error: ISO C++ does not support the ‘%lf’ gnu_printf format
kynan

2
@ kynan : 그렇다면 (g ++의 현재 버전을 가정하면) g ++의 버그입니다. C89 / 90 및 C ++ 98 / 03의 l경우 확장이 허용 되었습니다. C99 / 11 및 C ++ 11 표준은이를 구현하기 위해 구현이 필요합니다.
Jerry Coffin 2016 년

1
이상하게도 scanf 않는 희망 double의에 의해 표현은 %lf: 그것은 예상 불평 float *발견 double *단지와 함께 %f.
Eric Dand

1
@JerryCoffin g ++ ++ g에 여전히 기본값 98 모드
MM

5
@EricDand의 때문에 그 scanf때문에, 그것은 무엇을 읽고 저장하는 위치에 대한 포인터 걸리는 필요 반면 공간 인 얼마나 큰 알에서 뾰족한을-, printf값 자체 및 "기본 인수 프로모션"을 필요로 양단을 의미 double(가), 그래서 S l입니다 본질적으로 선택 사항입니다.
TripeHound

63

C99 표준 (즉, N1256 초안)이 주어지면 규칙은 함수 종류 fprintf (printf, sprintf, ...) 또는 scanf에 따라 다릅니다.

추출 된 관련 부품은 다음과 같습니다.

머리말

이 두 번째 버전은 ISO / IEC 9899 / COR1 : 1994, ISO / IEC 9899 / AMD1 : 1995 및 ISO / IEC 9899 / COR2 : 1996에 의해 수정 및 수정 된 첫 번째 버전 인 ISO / IEC 9899 : 1990을 취소하고 대체합니다. 이전 버전의 주요 변경 사항은 다음과 같습니다.

  • %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 변환 지정자가 long double 인수에 적용되도록 지정합니다.

지정된 동일한 규칙이 fprintf적용 printf, sprintf및 이와 유사한 기능을한다.

7.19.6.2 fscanf기능

11 길이 수정 자와 그 의미는 다음과 같습니다.

l (ell) 다음의 a, A, e, E, f, F, g 또는 G 변환 지정자가 double에 대한 포인터 유형의 인수에 적용되도록 지정합니다 (...).

L 다음 a, A, e, E, f, F, g 또는 G 변환 지정자가 long double에 대한 포인터 유형을 가진 인수에 적용되도록 지정합니다.

12 변환 지정자와 그 의미는 다음과 같습니다. a, e, f, g 선택적으로 부호있는 부동 소수점 숫자 (...)와 일치합니다.

14 변환 지정자 A, E, F, G 및 X도 유효하며 각각 a, e, f, g 및 x와 동일하게 작동합니다.

fprintf다음 지정자와 해당 유형에 대한 간략한 설명 이 지정됩니다.

  • %f -> 더블
  • %Lf -> 롱 더블.

그리고 fscanf그것은 :

  • %f -> 플로트
  • %lf -> 더블
  • %Lf -> 롱 더블.

25

그것은 할 수있다 %f, %g또는 %e당신이 수를 포맷하는 방법에 따라 달라집니다. 자세한 내용은 여기 를 참조하십시오. l수정이 필요하다 scanf으로 double하지만, NOT IN printf.


1
-1 : l(소문자) 수정자는 정수 유형 ( cplusplus.com/reference/clibrary/cstdio/printf ) L용이며 부동 소수점 유형용입니다. 또한 L수정자는 long double일반이 아닌을 기대합니다 double.
user470379

10
user470379 : 내 대답과 모순은 어디에 있습니까? 나는 상기하지 않았 l필요하지 않습니다 printf에 대한 double.
vitaut

15

형식 %lf은 사용했던 그대로에 printf대한 올바른 형식입니다 double. 코드에 아무런 문제가 없습니다.

C 언어의 이전 (C99 이전) 버전에서는 형식 %lfin printf이 지원되지 않았으며 doublein printf및의 형식 지정자간에 피상적 인 "일관되지 않음"이 발생 했습니다 scanf. 이 불일치가 C99에서 수정되었습니다.

에서 %lf와 함께 사용할 필요는 없습니다 . 원하는 경우 ( 와 동일 ) 에도 사용할 수 있습니다 . 그러나 현대 C에서 사용하는 것을 선호하는 완벽한 의미가 와 , 로 와 함께 지속적 모두에서 와 .doubleprintf%f%lf%fprintf%ffloat%lfdouble%Lflong doubleprintfscanf


으로 scanf(), "%f", "%lf"일치 float *, double *하지, float, double같은 마지막 줄에 의해 암시.
chux-복원 모니카

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.