Language

[ C++ ] sprintf, snprintf의 차이

궁금한게 많은 개발자 2020. 6. 16. 14:56

sprintf, snprintf는 패킷 통신을 하거나, buffer에 원하는 문자열을 삽입, 이어붙이기 할때 자주사용되는 함수들이다.

int snprintf ( char * s, size_t n, const char * format, ... );

int sprintf ( char * str, const char * format, ... );

 

첫번째 인자에 문자열을 저장할 배열을 넘겨주고, snprintf는 두번째인자로 저장할 배열의 크기, format에는 ""로 묶여진 서식지정자와 문자를 주면 버퍼에 해당내용이 저장되고, 리턴값으로는 buffer에 저장한 배열의 크기를 반환하게 된다.

아래는 sprintf와 snprintf의 예제이다.

/* sprintf example */
#include <stdio.h>

int main ()
{
  char buffer [50];
  int n, a=5, b=3;
  n=sprintf (buffer, "%d plus %d is %d", a, b, a+b);
  printf ("[%s] is a string %d chars long\n",buffer,n);
  return 0;
}
/* snprintf example */
#include <stdio.h>

int main ()
{
  char buffer [100];
  int cx;

  cx = snprintf ( buffer, 100, "The half of %d is %d", 60, 60/2 );

  if (cx>=0 && cx<100)      // check returned value

    snprintf ( buffer+cx, 100-cx, ", and the half of that is %d.", 60/2/2 );

  puts (buffer);

  return 0;
}

 

같은 기능을 한다고 볼수있지만, 명확한 차이점이 있으며 sprintf를 사용하기보다는 snprintf를 자주 사용하게 된다.  이유는 정해놓은 크기만큼 버퍼에 복사를하느냐, 아니면 format에 들어온 크기만큼 복사를 하느냐가 중요하다.

즉 안정성의 이유 때문인데, 받아오는 크기만큼 복사를 하게되면 buf의 size보다 큰 문자열을 받게된다면 오버플로우가 생길 수 있기때문!

아래와 같이 buf의 크기는 10으로 정해주고, 길이가 10보다 큰 문자열을 buf에 sprintf를 사용해 넣게되면 buf를 위해 할당한 메모리공간보다 더 사용하게 되므로, buf를 위해 사용하기로한 메모리와 상관없는 부분을 침범하기에 위험하다. 

#include <stdio.h>
int main()
{
    char buf[10];
    char str[] = "BBBBBBBBBBBB";
    sprintf(buf, "%s", str);
    printf("%s\n", buf);
}

이러한 이유에서 많이들 snprintf를 사용하는것을 추천하는것 같다.