C++控制台日志
我寫的代碼:
//頭文件包含 ClogFile.h#pragma once //設置local語言 #include <locale.h>#pragma warning(disable:4996)class Clog { public:inline Clog();inline ~Clog(); public://內斂函數,實現可以寫在頭文件里void inline WriteLogInfo(TCHAR * szLogInfo);void inline WriteLogInfo(unsigned char* szLogInfo, int len);void inline WriteLogInfo(LPCTSTR lpFormat, ...);void inline WriteLogInfo(LPCSTR lpFile, DWORD dwLine, LPCTSTR lpFormat, ...); };//構造函數 inline Clog::Clog() {//打開控制臺資源AllocConsole(); _tfreopen(_TEXT("CONOUT$"), _TEXT("w+t"), stdout );//申請寫//freopen( "CONIN$", "r+t", stdin ); //申請讀//設置控制臺標題TCHAR szProgramName[MAX_PATH];HMODULE hModule(NULL);GetModuleFileName(hModule, szProgramName, MAX_PATH);SetConsoleTitle(szProgramName);//正常顯示中文字符setlocale(LC_ALL,"chs"); }//析構函數 inline Clog::~Clog() {//釋放控制臺資源FreeConsole(); }//打日志函數 void inline Clog::WriteLogInfo(TCHAR * szLogInfo) {//日志信息,_tprintf函數支持ASCII和UNICODE_tprintf(_TEXT("%s\n"),szLogInfo); }void inline Clog::WriteLogInfo(unsigned char* szLogInfo, int len) {char *pTmp = new char[3*len + 1];ZeroMemory(pTmp, 3*len + 1);for (int i = 0; i < len; i++){char buf[4] = {0};_sntprintf(buf, 2, "%02x", szLogInfo[i]);buf[2] = ' ';strcat(pTmp+i*3, buf);}WriteLogInfo(pTmp);delete pTmp; }//支持字符串格式化 void inline Clog::WriteLogInfo(LPCTSTR lpFormat, ...) {//解析參數TCHAR szArgMessage[3000] = {0};va_list args;va_start(args, lpFormat);_vstprintf(szArgMessage, lpFormat, args);va_end(args);WriteLogInfo(szArgMessage); }//支持文件和行號信息,以及時間 void inline Clog::WriteLogInfo(LPCSTR lpFile, DWORD dwLine, LPCTSTR lpFormat, ...) {//所在文件名字char fileName[100] = {0};strcpy_s(fileName, 100, PathFindFileNameA(lpFile)); #ifdef UNICODE //從__FILE__獲得字符串肯定是ASCII的,根據環境改變編碼wchar_t fileName_w[100];mbstowcs(fileName_w, fileName, 100); #endif//獲取時間SYSTEMTIME st;TCHAR time[100];GetSystemTime(&st);_sntprintf(time, 100, _TEXT("%04d%02d%02d%02d%02d%02d"),st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);//解析參數TCHAR szArgMessage[3000] = {0};TCHAR szFullMessage[3000] = {0};va_list args;va_start(args, lpFormat);_vstprintf(szArgMessage, lpFormat, args);va_end(args);#ifdef UNICODE_sntprintf(szFullMessage, 3000, _TEXT("文件->%s 行號->%d 時間->%s 信息->%s"), fileName_w, dwLine, time, szArgMessage); #else_sntprintf(szFullMessage, 3000, _TEXT("文件->%s 行號->%d 時間->%s 信息->%s"), fileName, dwLine, time, szArgMessage); #endifWriteLogInfo(szFullMessage); }// //全局變量 static Clog gConsoleLog;//==================================================================================
別人源碼:
#if !defined(_LOGFILE_H__261C9DDC_AB17_4781_B87F_4B82DD38DD13__INCLUDED) #define _LOGFILE_H__261C9DDC_AB17_4781_B87F_4B82DD38DD13__INCLUDED#if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000#include <tchar.h> #include <stdio.h> #include <stdarg.h> #include <clocale> #include <cstdio> #include <shlwapi.h>#if !defined(ASSERT) #include <cassert> #define ASSERT assert #endif // !defined(ASSERT)#pragma comment(lib, "shlwapi.lib")#pragma warning(disable: 4996)/ /* CLogFile classRecording log is this class's work. */ class CLogFile { public:// Init CLogFile instance logger.static CLogFile* InitLogger(LPCTSTR lpLogName = NULL);// Record log to log file.static void Log(LPCSTR lpFile, DWORD dwLine, LPCTSTR lpFormat, ...);public:// Write log to log file method.void Write(LPCSTR lpFile, DWORD dwLine, LPCTSTR lpMessage);public:// Destructor.virtual ~CLogFile();public:class FOTracer{private:LPCSTR m_lpFile;DWORD m_dwLine;public:FOTracer(LPCSTR lpFile, DWORD dwLine): m_lpFile(lpFile), m_dwLine(dwLine){}void operator()(LPCTSTR lpFormat, ...);};friend class FOTracer;private:CLogFile(LPCTSTR lpLogName);CLogFile(const CLogFile &other);CLogFile& operator = (const CLogFile &);private:static CLogFile* m_pMe;private:FILE* m_pFile;CRITICAL_SECTION m_hWrCrtSec; };__declspec(selectany) CLogFile* CLogFile::m_pMe = NULL;#define InitializeLogger CLogFile::InitLogger #define LOG CLogFile::FOTracer(__FILE__, __LINE__)//************************************************************************************ Constructor. */ inline CLogFile::CLogFile(LPCTSTR lpLogName) { #if defined(LOG_CONSOLE) #if !defined(_CONSOLE)AllocConsole();_tfreopen(_T("CONOUT$"), _T("w+"), stdout);SetConsoleTitle(_T("Log Recorder"));HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_SCREEN_BUFFER_INFO csbiInfo = {0};GetConsoleScreenBufferInfo(hConsole, &csbiInfo);SMALL_RECT rect = csbiInfo.srWindow;COORD coord = {200, 600};rect.Right = 599;SetConsoleScreenBufferSize(hConsole, coord);SetConsoleWindowInfo(hConsole, FALSE, &rect);CloseHandle(hConsole); #endif // !defined(_CONSOLE) #else #if !defined(_DEBUG)m_pFile = _tfsopen(lpLogName, _T("a+"), 0x20);int nNum(1);while (!m_pFile){TCHAR szExtName[44] = {0};_stprintf(szExtName, _T(".%d.log"), nNum++);TCHAR szLogName[MAX_PATH] = {0};lstrcpyn(szLogName, lpLogName, MAX_PATH);PathRenameExtension(szLogName, szExtName);m_pFile = _tfsopen(szLogName, _T("a+"), 0x20);} #endif // !defined(_DEBUG) #endif // defined(LOG_CONSOLE)InitializeCriticalSection(&m_hWrCrtSec); }/************************************************************************************ Copy constructor. */ inline CLogFile::CLogFile(const CLogFile &other) {*this = other; }/************************************************************************************ Operator assignment overload. */ inline CLogFile& CLogFile::operator = (const CLogFile&) {return *this; }/************************************************************************************ Constructor. */ inline CLogFile::~CLogFile() {DeleteCriticalSection(&m_hWrCrtSec);#if defined(LOG_CONSOLE) #if !defined(_CONSOLE)FreeConsole(); #endif // !defined(_CONSOLE) #else #if !defined(_DEBUG)if (m_pFile){fclose(m_pFile);} #endif // !defined(_DEBUG) #endif // defined(LOG_CONSOLE) }/************************************************************************************ Init CLogFile instance logger. */ inline CLogFile* CLogFile::InitLogger(LPCTSTR lpLogName/* = NULL*/) {if (!m_pMe){_tsetlocale(LC_ALL, _T("chs"));TCHAR szLogName[MAX_PATH] = {0};if (lpLogName){lstrcpyn(szLogName, lpLogName, MAX_PATH);}else{HMODULE hModule(NULL); #if defined(GetModuleHandleEx)LPCTSTR pszModuleName = (LPCTSTR)InitLogger;GetModuleHandleEx(0x00000004, pszModuleName, &hModule); #endif // defined(GetModuleHandleEx)GetModuleFileName(hModule, szLogName, MAX_PATH);PathRenameExtension(szLogName, _T(".log"));}static CLogFile Me(szLogName);m_pMe = &Me;}return m_pMe; }/************************************************************************************ Write log to log file method. */ inline void CLogFile::Write(LPCSTR lpFile, DWORD dwLine, LPCTSTR lpMessage) {LPCSTR lpFileName = PathFindFileNameA(lpFile);TCHAR szFileName[MAX_PATH] = {0}; #if defined(_UNICODE) || defined(UNICODE)mbstowcs(szFileName, lpFileName, MAX_PATH); #elselstrcpyn(szFileName, lpFileName, MAX_PATH); #endif // defined(_UNICODE) || defined(UNICODE)TCHAR szDateTime[256] = {0};TCHAR szLogMessage[4096] = {0};SYSTEMTIME st = {0};GetLocalTime(&st);_stprintf(szDateTime, _T("%04d%02d%02d %02d:%02d:%02d:%03d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);_stprintf(szLogMessage, _T("[%s][%d][%d][%s:%d]%s\n"), szDateTime, GetCurrentProcessId(), GetCurrentThreadId(), szFileName, dwLine, lpMessage);EnterCriticalSection(&m_hWrCrtSec);#if defined(LOG_CONSOLE)_tprintf(szLogMessage); #else#ifdef _DEBUGOutputDebugString(szLogMessage); #else_fputts(szLogMessage, m_pFile);fflush(m_pFile); #endif // _DEBUG#endif // !defined(LOG_CONSOLE)LeaveCriticalSection(&m_hWrCrtSec); }/************************************************************************************ Record log to log file. */ inline void CLogFile::Log(LPCSTR lpFile, DWORD dwLine, LPCTSTR lpFormat, ...) {ASSERT(NULL != m_pMe);if (m_pMe){TCHAR szMessage[3030] = {0};va_list args;va_start(args, lpFormat);_vstprintf(szMessage, lpFormat, args);va_end(args);m_pMe->Write(lpFile, dwLine, szMessage);} }inline void CLogFile::FOTracer::operator()(LPCTSTR lpFormat, ...) {ASSERT(NULL != CLogFile::m_pMe);if (CLogFile::m_pMe){TCHAR szMessage[3030] = {0};va_list args;va_start(args, lpFormat);_vstprintf(szMessage, lpFormat, args);va_end(args);CLogFile::m_pMe->Write(m_lpFile, m_dwLine, szMessage);} }#endif // !defined(_LOGFILE_H__261C9DDC_AB17_4781_B87F_4B82DD38DD13__INCLUDED)總結
- 上一篇: 引用传参和指针传参
- 下一篇: forceinline关键字