시작은 미미하나 끝은 쥬쥬하리라.

Develop/Language - C++

[C++] sprintf() vs snprintf()

코딩뚜벅이 2026. 1. 23. 15:57
반응형

목차

1. sprintf() vs snprintf()

2. 응용/심화

3. 요약

 


1. sprintf() vs snprintf()

 

sprintf :

sprintf 함수는 문자열을 생성하는 함수.printf()와 유사하지만 출력 대신 문자열을 버퍼에 저장.

 

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

 

- str : format을 복사해서 저장할 곳.

- format : 서식지정자가 포함된 문자열

- 반환 : 생성에 성공한 문자의 개수. (실패 -1)

- 배열 크기를 넘어서는 문자열을 저장하면 버퍼 오버플로우 발생.

 

#include <stdio.h>

void MyFunc() {
    char buff[30];
    int n1 = 1;
    int n2 = 2;
    sprintf(buff, "n1 = %d, n2 = %d", n1, n2);
    printf("%s", buff);
    return 0;
}

// n1 = 1, n2 = 2 출력

 

 

snprintf :

sprintf() 함수와 기능적으로 동일하나 버퍼 크기를 인자로 받아 버퍼 오버플로우를 방지하는 포맷팅 함수.

리턴값으로 잘림과 에러를 구분하는 것이 가능.

-> 버퍼 크기를 초과하는 데이터가 들어오면 size - 1까지만 쓰고 마지막에는 반드시 NULL 종단 문자를 붙여서 마무리.

-> 리턴값은 버퍼 크기 제한이 없었다면 썼을 전체 길이를 반환. (실제로 쓴 길이가 아님)

-> 반환값이 size보다 크거나 같다면 데이터가 잘렸다는 의미.

 

int snprintf(char *str, size_t size, const char *format, ...);
char buffer[16];
int n = snprintf(buffer, sizeof(buffer), "DEV:%s", deviceName);

// 1. 에러 발생 여부 확인 (음수 리턴)
if (n < 0) {
    HandleFormattingError();
}
// 2. 잘림 발생 여부 확인 (버퍼 크기보다 크거나 같음)
else if (n >= (int)sizeof(buffer)) {
    // 로그가 잘렸음을 사용자나 시스템에 알림
    LogWarning("Message truncated: original length was %d", n);
}

 

 


2. 응용/심화

포맷 스트링 취약점

snprintf()와 같이 외부 입력을 직접 포맷 인자로 넣는 행위는 매우 위험.

ex) sprintf(buffer, size, input);

-> input 대로 포맷을 맞춰서 출력 : input에 문자열 대신 %x혹은 %n과 같은 특수 기호를 사용하면 오동작.

-> %x는 메모리 주소를 16진수로 보여달라는 명령으로 메모리 정보를 화면에 출력하는 케이스 발생.

-> %n은 특정 메모리 주소의 값을 바꾸는 것이 가능하며 프로그램 주도권에까지 영향이 가능.

 

안전한 코드 :

snprintf(buffer, size, "%s", input)

 

- 포맷 인자를 %s로 고정하면 input에 어떠한 기호가 오더라도 문자로 인식하여 처리. (명령어로 인식되지 않음)

 


3. 요약

sprintf : 문자열을 버퍼에 저장하는 함수, 버퍼 사이즈 체크 하지 않음, 에러 검출 불가.

-> 안정성 낮고, C90/C99/C++에서 지원.

snprintf : 문자열을 버퍼에 저장하는 함수, 버퍼 사이즈 체크 함, 에러 검출 가능.

-> 안정성 높고, C99/C++11에서 지원.

 

- 프로그램 안정성을 위해서는 sprintf, strcpy와 같이 크기를 지정하지 않는 함수의 사용을 자제.

- snprintf 호출 이우에는 반드시 반환값과 버퍼 크기를 비교하여 데이터 유실 여부 판단.

반응형

'Develop > Language - C++' 카테고리의 다른 글

[C++] 메모리 / 핸들 누수 및 추적 도구  (0) 2026.01.25
[C++] C++ 기호 시퀀스  (0) 2026.01.25
[C++] _wtoi, wcstoul  (0) 2026.01.23
[C++] Size vs Capacity  (0) 2026.01.23
[C++] size_t  (0) 2026.01.23