반응형

C/C++ 포맷스트링


디버깅 환경이 별도로 구현되지 않은 프로젝트에서는 윈도우 기본 디버그 API인 OutputDebugString()을 사용해서 디버그 로그를 출력한다.

그러나 OutputDebugString()은 가변 인자 포맷 스트링(Formatted String)을 지원하지 않아서 상당히 불편하다.

 

MFC 환경에서라면 CString의 Format()으로 문자열을 어느 정도 구현할 수 있겠지만,

다른 C/C++ 프로젝트 환경에서는 std::stringstd::wstring을 주로 사용하기 때문에 포맷스트링을 매번 구현하기가 번거로운 편이다.

 

그래서 자주 사용되는 std::string의 포맷스트링 구현을 간단히 작성해두고 그대로 복사하여 사용한다.

 

아래에 멀티바이트(std::string) 및 유니코드(std::wstring) 환경에서 사용할 수 있는 두 가지 구현 코드사용 예제를 작성해두었다.

각 사용 환경에 따라 적절히 수정해서 활용하자.

728x90

 

std::string 포맷스트링 구현


멀티바이트 문자 집합(MBCS)용 구현 (std::string)

std::string format_arg_list(const char *fmt, va_list args)
{
    std::string s;

    if (fmt != nullptr)
    {
        int result = -1, length = 512;
        char *buffer = nullptr;
        
        while (result == -1)
        {
            if (buffer)
            {
                delete[] buffer;
            }
            buffer = new char[length + 1];
            memset(buffer, 0, (length + 1) * sizeof(char));

            result = _vsnprintf_s(buffer, length, _TRUNCATE, fmt, args);
            length *= 2;
        }
        
        s = buffer;
        delete[] buffer;
    }

    return s;
}
void DebugMessage(const char *fmt, ...)
{
    std::string msg;

    va_list ap;
    va_start(ap, fmt);
    msg = format_arg_list(fmt, ap);
    va_end(ap);

    msg += "\n";

    OutputDebugString(msg.c_str());
}

 

유니코드 문자 집합용 구현 (std::wstring)

std::wstring format_arg_list(const wchar_t *fmt, va_list args)
{
    std::wstring s;

    if (fmt != nullptr)
    {
        int result = -1, length = 512;
        wchar_t *buffer = nullptr;
        
        while (result == -1)
        {
            if (buffer)
            {
                delete[] buffer;
            }
            buffer = new wchar_t[length + 1];
            memset(buffer, 0, (length + 1) * sizeof(wchar_t));

            result = _vsnwprintf_s(buffer, length, _TRUNCATE, fmt, args);
            length *= 2;
        }
        
        s = buffer;
        delete[] buffer;
    }

    return s;
}
void DebugMessage(const wchar_t *fmt, ...)
{
    std::wstring msg;

    va_list ap;
    va_start(ap, fmt);
    msg = format_arg_list(fmt, ap);
    va_end(ap);

    msg += L"\n";

    OutputDebugString(msg.c_str());
}
반응형

+ Recent posts