/////////////////////////////////////////////////////////////////////////////
/*Log.h*/
#define MAX_BUFFER_LENGTH 1024
class CLog
{
public:
// 생략기호(ellipsis)인...는 컴파일러에게 이후의 인수에 대해서는 개수와 타입을 점검하지 않도록 한다. 이 기호에 의해 가변인수를 사용할 수 있다.
static BOOL WriteLog(LPTSTR data, ...)
{
SYSTEMTIME SystemTime;
TCHAR CurrentDate[32] = {0, };
TCHAR CurrentFileName[MAX_PATH] = {0, };
FILE* FilePtr = NULL;
TCHAR DebugLog[MAX_BUFFER_LENGTH] = {0, };
TCHAR Log[MAX_BUFFER_LENGTH] = {0, };
// va_list = char*형, 가변인수를 읽기 위해 포인터변수를 선언했다고 생각하면 된다.
va_list ap;
// va_start(가변인수, 마지막 고정변수)
// 가변인수 ap를 고정변수data 다음의 메모리에 올리고 초기화한다.
// va_arg(ap, 인자타입) 인자타입을 받아 ap부터 반복적으로 다음 인자를 리턴한다.
va_start(ap, data);
// 로그에 데이터를 입력한다.
_vstprintf_s(Log, _countof(Log), data, ap);
// va_end(ap) 가변인수를 다 읽은 후 뒷정리한다.
va_end(ap);
// 시스템시간 가져오기
GetLocalTime(&SystemTime);
// 현재 데이터변수에 현재 시간을 저장한다.
_sntprintf_s(CurrentDate, _countof(CurrentDate), 32, _T("%02d-%02d-%02d %02d:%02d:%02d"),
SystemTime.wYear,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond);
// 현재 파일이름을 저장한다.
_sntprintf_s(CurrentFileName, _countof(CurrentFileName), MAX_PATH, _T("LOG_%04d-%02d-%02d %02d.txt"),
SystemTime.wYear,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour);
// 파일이 없으면 파일을 생성하고 파일이 있으면 존재하는 파일내용 다음에 쓴다.
_tfopen_s(&FilePtr, CurrentFileName, _T("a"));
// 생성이 되지 않으면
if(!FilePtr)
return FALSE;
// 파일에 현재 날짜와 로그를 입력한다.
_ftprintf(FilePtr, _T("[%s] %s\n"), CurrentDate, Log);
// 디버그 로그에 현재 날짜와 로그를 입력한다.
_sntprintf_s(DebugLog, _countof(DebugLog), MAX_BUFFER_LENGTH, _T("[%s] %s\n"), CurrentDate, Log);
// 버퍼를 해제한다.
fflush(FilePtr);
// 파일을 닫는다.
fclose(FilePtr);
// 디버그 로그를 출력한다.
OutputDebugString(DebugLog);
_tprintf(_T("%s\n"), DebugLog);
return TRUE;
}
};
////////////////////////////////////////////////////////////////////////////////////