본문 바로가기

C/C++/Tip

[문자열 처리] sprintf 와 snprintf 의 차이점.

반응형

문자열 처리 함수 sprintf / snprintf 의 차이점.

 

패킷 통신을 할때 주로 char 배열 형태의 버프로

패킷을 주고 받는다.

이때 패킷을 만들어서 보낼땐 sprintf 나 snrpintf 를 사용하고,

받은 패킷을 파싱할땐 snrpintf 를 사용 한다.

 

 

둘다 똑같이 문자열을 붙여주는데 왜 하나로 통일해서 쓰지 않느냐 !!

이건 두개의 함수에 엄청난 차이점이 있기 때문이다.

 

 

buf 라는 변수에 아래와 같이 값이 있다고 할때.

buf 0

1

2

3

4

5

6

7

8

9

a

b

c

d

e

f

g

h

i

NULL

 

 

나에게 "abc" 만이 필요하다면

 

 

sprintf(abc, "%-*s", 3, buf);

snrpintf(abc, 4, "%-*s", 3, buf);

 

 

이렇게 위의 소스로 abc 라는 배열안에 값을 복사 해올수 있다.

 

 

이제 갖고온 abc의 값을 찍어보면 ?

sprintf 와 snprintf 의 차이를 명확히 알수 있게된다.

 

 

먼저 sprintf 로 복사를 해온 abc 를 찍어보면

 

abc 안의 값이 buf의 값과 동일하게 나오게 된다.

"abcdefghi" 까지 모두 ~

 

 

abc 의 사이즈는 겨우 4칸인데도 10자리를 가진 buf 의 값을 모두 갖고 오게된다.

 

다른 변수의 메모리 영역까지 침범을 할수 있는 무서운 부분이다.

 

반면 snprintf 는 정상적으로 "abc" 의 값만이 채워져 있다.

 

 

이러한 차이가 보이는건,

snprintf 는 사용자가 두번째 인자값으로 넘긴 만큼만 갖고오면서, 마지막 주소지엔 알아서 널값을 채워주기 때문

내가 원하는 3개의 값이 출력 되는것이고,

 

sprintf 는 그런 인자값이 없기 때문에

Null 값이 있는부분까지 죄다 긁어오게 된다.

 

%-3s 를 해서 3자리만 갖고오겠다고 하지 않았냐는 생각이 들수도 있는데,

 

%-3s 는 좌측 정렬을 하고 혹시 비는공간이 있으면 최대 3자리 까지 스페이스바 처리를 해주는 방법이지,

3자리만 갖고오겠단 뜻이 아니므로

%s 의 규칙인 "시작지부터 Null 까지~" 를 통해 죄다 복사가 된거다 !

 

정확하게 자리수가 딱딱 들어맞는 것들을 패킷으로 만들때가 아니라면,

snprintf 를 활용하는게 더 좋다고 본다.


반응형