본문 바로가기

강의자료/C/C++

TIP. printf()함수처럼 가변인자를 이용한 문자열 생성하기.


문자열 관련 코드는 MBCS(멀티바이트 문자 집합)와 UNICODE 이렇게 2가지 형식을 항상 염두에 두고 작성해야 합니다. 여기에 작성할 코드 역시 문자열 코드이기때문에 2가지 형식을 나누어서 작성하도록 하겠습니다.

MBCS는 char 타입을 사용하고, UNICODE는 wchar_t 타입을 사용합니다. 그리고 컴파일러의 셋팅에 따라 MBCS 또는 UNICODE를 사용할 수 있도록 호환성을 유지하고 싶을 경우에는 TCHAR 타입을 사용하면 됩니다.

비주얼 스튜디오 6.0버전은 기본값이 MBCS를 사용하도록 되어있고 그 이후의 닷넷 버전 비주얼 스튜디오는 기본값이 UNICODE를 사용하도록 되어있습니다. 때문에 UNICODE를 위한 코드부분에서는 wchar_t 타입을 사용하지 않고 TCHAR 타입을 사용하도록 하겠습니다. 어차피 현재 가장 많이 사용하는 비주얼 스튜디오 2008에서는 TCHAR 타입을 쓰면 UNICODE로 작동하게 되어있기때문에 MBCS를 사용하기 위한 char 타입 방식만 알고 있으면 두가지 방법 모두를 사용할 수 있기때문입니다.

아래 UNICODE 버전은 문자열을 입력받고 메시지 박스로 출력하는 함수입니다. 문자열을 구하는 부분은 va_start() 부터 va_end() 까지만 보시면 됩니다.
 
코드 복사 (UNICODE 버전)
	
void TraceMessageBox( TCHAR * szCaption, TCHAR * szFormat, ... )
{
	// 가변인자로부터 문자열 얻기.
	va_list args;
	int len;
	TCHAR * buffer;

	// 시작.
	va_start( args, szFormat );
	// 가변인자로 이루어진 문자열의 크기를 구한다.
	len = _vsctprintf( szFormat, args ) + 1; // _vscprintf doesn't count terminating '\0'
	// 위에서 구한 크기+1만큼 buffer에 메모리를 할당한다.
	buffer = static_cast(malloc( len * sizeof(TCHAR) ));
	// 문자열을 buffer에 입력한다.
	_vstprintf_s( buffer, len, szFormat, args );
	// 끝.
	va_end( args );

	MessageBox(NULL, buffer, szCaption, MB_OK);
	free( buffer );
}	


아래 MBCS 버전은 메시지를 입력받아서 새로운 콘솔창을 생성하여 출력하는 예제입니다. 간단하게 디버깅 용도로 사용할 수 있도록 작성하였습니다. 마찬가지로 가변인자로부터 문자열을 구하는 부분은 Write()함수 내에서 va_start() 부터 va_end() 까지만 보시면 됩니다.
 
코드 복사 (MBCS 버전)
	
class DebugConsole 
{ 
public : 
	DebugConsole( ) 
	{ 
	#ifdef _DEBUG 

		AllocConsole( ); 
		_hConsole = GetStdHandle( STD_OUTPUT_HANDLE ); 

	#endif 
	}

	~DebugConsole( ) 
	{ 
	#ifdef _DEBUG 

		FreeConsole( ); 

	#endif 
	}

	void Write(char * format, ...)
	{
	#ifdef _DEBUG
		
		va_list args;
		int len;
		char * buffer;
		
		va_start( args, format );
		len = _vscprintf( format, args ) + 1; // _vscprintf doesn't count terminating '\0'
		buffer = (char *)malloc( len * sizeof(char) );
		vsprintf_s( buffer, len, format, args );

		va_end( args );

		//HANDLE hOut;
		DWORD dwWrite;
		//hOut = GetStdHandle( STD_OUTPUT_HANDLE );
		WriteFile(_hConsole,buffer,strlen(buffer),&dwWrite,NULL);

		free(buffer);

	#endif 
	}

private : 
	HANDLE  _hConsole; 
};