programing

sprintf 버퍼 크기 결정 - 표준 규격은 무엇입니까?

prostudy 2022. 6. 3. 22:34
반응형

sprintf 버퍼 크기 결정 - 표준 규격은 무엇입니까?

다음과 같이 int를 변환하는 경우:

char a[256];
sprintf(a, "%d", 132);

a의 크기를 결정하는 가장 좋은 방법은 무엇일까요?(어디서나 사용하던 것처럼) 수동으로 설정해도 괜찮을 것 같습니다만, 어느 정도의 크기가 좋습니까?32비트 시스템에서 가능한 최대 int 값은 얼마입니까?또, 그것을 즉석에서 판별하는 까다로운 방법이 있습니까?

여기 있는 몇몇 사람들은 이 접근법이 과잉이라고 주장하고 있고, ints를 문자열로 변환하는 것에 대해서는 좀 더 동의할 수 있을 것 같습니다.그러나 문자열 크기에 대한 적절한 바운드를 찾을 수 없을 때 이 방법을 직접 사용해 본 적이 있습니다.

int size = snprintf(NULL, 0, "%d", 132);
char * a = malloc(size + 1);
sprintf(a, "%d", 132);

여기서 무슨 일이 일어나고 있는지 설명해줄게.

  1. 첫 번째 줄에는 몇 글자가 필요한지 알아보겠습니다.'2'에 대한 첫 snprintf로 .NULL 할 때 ★★★★★★★★★★★★★★★★★★★★★★.snprintf실제로 아무 문자도 쓰지 않고 단순히 쓰여진 문자 수를 반환합니다.이게 우리가 원하던 거야
  2. 줄에서는 메모리를 하고 있습니다.char 을 붙여서 꼭 1.\0★★★★★★★★★★★★★★★★★★」
  3. 이 충분해졌습니다.char할 수 .sprintfchar포인터

물론 당신이 원한다면 더 간결하게 만들 수 있습니다.

char * a = malloc(snprintf(NULL, 0, "%d", 132) + 1);
sprintf(a, "%d", 132);

프로그램이 , '빠른' 이나 '빠른' 프로그램이나 '' 프로그램이나 '' 프로그램이나 '빠른' 프로그램이나 '빠른' 프로그램이나 '빠른' 프로그램이나 '빠른' 프로그램이나 '빠른' 프로그램이나 '빠른' 프로그램이나 '빠른'으로 호출한 메모리를 .malloc여기서 C와 함께 다이내믹 어프로치가 복잡해집니다.는 큰 IMHO를 할당하지 않습니다.char포인터는 대부분의 시간 동안 아주 적은 부분만을 사용하게 될 때, 저는 이것이 나쁜 접근이라고 생각하지 않습니다.

C++11/C99에 있는 vsnprintf를 사용하면 Daniel Standage의 솔루션을 임의의 수의 인수에 대해 작동시킬 수 있습니다.

int bufferSize(const char* format, ...) {
    va_list args;
    va_start(args, format);
    int result = vsnprintf(NULL, 0, format, args);
    va_end(args);
    return result + 1; // safe byte for \0
}

c99 표준 섹션 7.19.6.12에 명시된 바와 같이:

vsnprintf 함수는 부호화 오류가 발생한 경우 끝의 늘 문자를 카운트하지 않거나 음의 값을 카운트하지 않고 n개 충분히 컸을 경우 기입되었을 문자 수를 반환합니다.

우선, sprintf는 악마이다.snprintf를 사용하지 않으면 메모리가 파괴되어 앱이 다운될 위험이 있습니다.

버퍼 사이즈에 대해서는 다른 모든 버퍼와 마찬가지로 가능한 한 작게, 필요한 만큼 크게 합니다.당신의 경우 부호 있는 정수를 가지고 있으므로 가능한 한 큰 사이즈를 선택하시고 약간의 안전 패딩을 추가하셔도 됩니다."표준 크기"는 없습니다.

또, 사용하고 있는 시스템에 의해서도 다릅니다.(예시와 같이) 스택에 버퍼를 정의할 경우 스택의 크기에 따라 달라집니다.사용자가 직접 스레드를 작성한 경우 스택 크기를 직접 결정하여 제한을 파악할 수 있습니다.재귀 또는 딥 스택트레이스를 예상할 경우 주의할 필요가 있습니다.

는 int입니다.CHAR_BIT * sizeof(int)의 10비트의 3비트에 합니다.int(CHAR_BIT * sizeof(int) / 3) + 3이 +3은 분할할 때 반올림한 사실을 나타내는 것입니다.하나는 기호용, 다른 하나는 눌 터미네이터용입니다.

a bit system은 "32비트 시스템"을 알고 있음을 합니다.int32비트가 되면 12바이트가 필요합니다.10은 자리수, 1은 부호, 1은 눌 터미네이터입니다

의 경우, 는 「」, 「」의 int 입니다.132 4바이트가 필요해요.둠,, 티티.

고정 사이즈의 버퍼를 적절한 범위로 사용할 수 있는 경우는, 이러한 버퍼가 보다 간단한 옵션입니다.하다고는 할 수 없습니다(의 경우 13바이트는 12비트입니다(32비트에서는 12바이트).int, '64'가 '21'이 '23'이 됩니다int)., 로 전화하면 .), C99로 전화하면 snprintf , 에 (사이즈를) 구합니다.malloc치고는 그건이야.이런 간단한 사건치고는 그건 과잉 살상이야.

이 대화는 몇 년 전의 대화입니다만, snprintf 를 사용해 사이즈를 확인할 수 없는 MS VC++ 의 회답을 찾으려고 하고 있었습니다.다른 사람에게 도움이 될 경우에 대비하여 최종적으로 찾은 답을 게시하겠습니다.

VC++에는 필요한 문자 수를 찾는 기능이 있습니다.

단순한 정수를 인쇄하는 경우 출력 버퍼 크기를 결정하는 훨씬 더 간단한 방법이 있습니다.적어도 계산상으로는 간단하지만 코드는 약간 둔감하다.

char *text;
text = malloc(val ? (int)log10((double)abs(val)) + (val < 0) + 2 : 2);

log10(value)은 0이 아닌 양의 값을 베이스 10에 저장하는 데 필요한 자릿수(소수 1)를 반환합니다.1보다 작은 숫자에 대해서는 약간 어긋나기 때문에 abs()를 지정하고 0에 대해서는 코드 특수 로직(3진 연산자, test? truecase: falsecase)을 지정합니다.음수 기호(val < 0)를 저장하기 위한 공간(val < 0)을 추가하고, log 10과의 차이를 보충하기 위한 공간(총 2의 경우)을 추가합니다.그러면 작업을 완료하기 위해 snprintf() 또는 동등한 값을 두 번 호출하지 않고 특정 숫자에 필요한 정확한 저장 공간을 계산한 것입니다.또한 일반적으로 INT_MAX에 필요한 것보다 적은 메모리를 사용합니다.

단, 많은 숫자를 매우 빠르게 인쇄해야 할 경우에는 INT_MAX 버퍼를 할당한 후 반복하여 인쇄하십시오.메모리 스레싱을 줄일수록 좋습니다.

또한 (플로트)가 아닌 (더블)이 실제로 필요하지 않을 수도 있습니다.굳이 확인하지 않았어요.그렇게 앞뒤로 던지는 것도 문제가 될 수 있어요.YMMV가 전부입니다.그래도 나한테는 잘 먹히긴 하는데

버퍼 사이즈가 걱정되어 다행입니다.그 생각을 코드에 적용하려면 snprintf를 사용합니다.

snprintf( a, 256, "%d", 132 );

또는

snprintf( a, sizeof( a ), "%d", 132 );  // when a is array, not pointer

언급URL : https://stackoverflow.com/questions/3919995/determining-sprintf-buffer-size-whats-the-standard

반응형