%G를 가진 Sprintf의 최소 버퍼 크기는 얼마입니까?
문제
문제는 최대 정밀도에서 %g로 형식으로 인쇄 된 이중을 맞출 수있을만큼 큰 버퍼를 정적으로 할당하는 것입니다. 이것은 충분히 간단한 작업처럼 보입니다. BU 문제가 있습니다. 내가 생각해 낸 최고는 (인쇄 할 숫자가 x라고 가정)입니다.
char buf[1 + DBL_DIG + DBL_DIG + 1 + 1 + 1 + DBL_DIG + 1];
int len = sprintf(buf, "%.*g", DBL_DIG, x);
DBL_DIG 매크로는 float.h에서 왔으며 분명히 유형의 두 배의 최대 정밀도를 나타냅니다. 우리는 필요합니다 :
- 부정적인 부호의 경우 1 바이트
- 중요한 숫자를 캡처하기에 충분한 바이트
- 숫자 당 최대 한 '분리기'숯 (쉼표 등)
- 소수점의 경우 1 바이트
- 'e'의 경우 1 바이트
- 지수의 부호는 1 바이트입니다
- 지수의 일부 바이트
- Sprintf가 작성한 후진 Null의 경우 1 바이트.
지수의 숫자 숫자 수의 상한으로 중요한 숫자 수를 사용하고 있습니다. 오류가 발생 했습니까? 더 나은 솔루션이 있습니까? 64, 128 또는 256 바이트를 할당하고 최선을 다해야합니까?
해결책 4
사용하는 대신 sprintf
, 당신은 사용할 수 있습니다 asprintf
. 이것은 문자열에 맞게 올바른 크기의 버퍼를 할당합니다.
다른 팁
컴파일 시간에 크기를 사전 계산할 수 없습니다. %g 형식은 로케일을 고려하여 (1000의 분리기 등) http://linux.die.net/man/3/sprintf 크기를 안전하게 계산하는 방법에 대한 설명.
사용 snprintf()
필요한 문자 수를 알아 보려면 :
#include <float.h> /* DBL_DIG */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double x = rand() / (double)RAND_MAX;
char find_len[1];
int need_len;
char *buf;
need_len = snprintf(find_len, 1, "%.*g", DBL_DIG, x);
buf = malloc(need_len + 1);
if (buf) {
int used = sprintf(buf, "%.*g", DBL_DIG, x);
printf("need: %d; buf:[%s]; used:%d\n", need_len, buf, used);
free(buf);
}
return 0;
}
C99 컴파일러가 필요합니다 snprintf()
.
snprintf()
C99 표준에 의해 정의되었습니다. C89 구현에는 필요하지 않습니다 snprintf()
정의되고 확장으로 정의 된 경우 C99 표준에 의해 설명 된대로 "작업"할 필요는 없습니다.
두 가지 : %g는 모든 대표 숫자를 보여주지는 않습니다. %g는 인간의 반올림 결과를 보여줍니다. 다른 결과를 원할 경우 %f 또는 %e를 사용하여 정밀도를 지정할 수 있습니다.
snprintf ()를 사용하지 않고 sprintf ()를 사용하지 마십시오. 귀하의 경우 :int len = snprintf(buf, dimensionof(buf), "%.*f", DBL_DIG, x);
64, 128 또는 256까지 반올림하고 최선을 다해야합니까?
예, 그냥 해요 -.-