컴퓨터 공학/C++

C++ Printf 검사 프로그램

혼새미로 2020. 2. 24. 21:50
반응형
C++에서 printf() 함수를 사용하면 원하는 변수를 파라미터로 전달하여 원하는 포맷으로 문자열을 출력할 수 있다.


string name = "Kim";
printf("My name is %s", name.c_str());


여기서 파라미터로 값을 전달하는 부분을 %d, %s와 같은 포맷 지정자 (format specifier)를 통해 타입과 위치를 지정할 수 있고, 쉼표를 통해 뒤에 파라미터를 전달해주면 된다.

문제는 포맷 지정자의 개수와 실제 전달하는 파라미터의 개수가 사용자의 실수로 얼마든지 달라질 수 있다는 점이다.


string name = "Kim";
printf("My name is %s and my hobby is %s\n", name.c_str()); // INFO: 프로세스 종료
printf("Hello world\n"); // INFO: 출력되지 않음


위 코드와 같이 포맷 지정자는 이름과 취미 두 개인 반면, 실제 전달하는 파라미터는 한 개밖에 없다. 이에 따라, 실제로 빌드하여 실행해보면 두 번째 라인에서 프로세스가 죽는 바람에 세 번째 라인의 "Hello world"가 출력되지 않는다.

포맷 지정자와 파라미터 개수가 다르다고 해서 컴파일러가 인식하여 오류를 표출하지도 않기 때문에 평소에 이러한 실수를 범할 가능성이 높다.

이에 나는 printf의 포맷 지정자 개수와 실제 전달하는 파라미터 개수를 검사하는 프로그램을 개발하기로 하였다.
Node.js 기반의 간단한 프로그램이다. 이 프로그램의 검사 대상은 다음과 같다.

[검사대상]
  • 프로그램을 위치를 루트 디렉토리로 하여 자식 폴더를 포함하여 모든 소스코드와 헤더파일의 printf() 함수를 찾는다.
  • 포맷 지정자의 개수 (%d, %s 등)와 실제 전달한 파라미터 개수가 동일한지 검사한다. 다르면 해당 부분 표시 후 종료한다.

테스트할 코드는 다음과 같다.


#include <iostream>
#include <string>
using namespace std;

void main() {
string name = "Kim";
printf("My name is %s and my hobby is %s\n", name.c_str()); // INFO: 프로세스 종료
printf("Hello world\n"); // INFO: 출력되지 않음
}


실제로 log_checker.exe를 실행하면 다음과 같은 결과가 표출된다.




마지막에 main.cpp 파일에서 printf()가 있는데, 포맷 지정자가 두 개인 반면 실제 전달하는 파라미터는 한 개밖에 없어 이 부분이 문제라는 것을 알려주고 있다. 개발자는 해당 부분을 찾아 소스코드를 수정함으로써 문제를 해결할 수 있다.

전체 프로젝트 소스는 여기서 볼 수 있다.


반응형