實現日誌類

1 實現c++ 類似 cout 類
2 就要實現 operator <<
3 在最後的一個 << 輸出
4 輸出到文件
5 整個文件使用一個文件輸出
6 支持寬字符,ANSI , 整型,如果自己想可以擴展自己的類型。

// logLib.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <string>
#include <direct.h>

std::wstring ansi2wide(const char *s)
{
	int n = MultiByteToWideChar(CP_ACP,0,s,-1,NULL,NULL);
	std::wstring ret(n-1,0);
	MultiByteToWideChar(CP_ACP,0,s,-1,(LPWSTR)ret.data(),ret.size());
	return ret;
}
std::string wide2ansi(const wchar_t* s)
{
	int n = WideCharToMultiByte(CP_ACP,0,s,-1,0,0,0,0);
	std::string ret(n-1,0);
	WideCharToMultiByte(CP_ACP,0,s,-1,(LPSTR)ret.data(),ret.size(),0,0);
	return ret;
}
class logBuilder
{
public:
	logBuilder(const char* filename)
	{
		_fp = fopen(filename,"ab+");
	}
	~logBuilder()
	{
		if(_fp)
		{
		fclose(_fp);
		}
	}
	FILE* file()
	{
	return _fp;
	}
private:
	FILE * _fp;
};
class mylog
{
public:
	enum {
		MODE_FILE,
		MODE_DEBUG,
		MODE_BUILDER,
	};
	mylog(){
		_flag = MODE_DEBUG;
	}
	mylog(logBuilder &log_builder)
	{
		_flag = MODE_BUILDER;
		_fp = log_builder.file();
	}
	
	mylog(const char* filename)
	{
		_fp = fopen(filename,"ab+");
		_flag = MODE_FILE;
	}
	mylog & operator << (const char* s)
	{
		_str+=s;
		return *this;
	}
	~mylog()
	{
		if(_flag == MODE_FILE)
		{
		fwrite(_str.data(),1,_str.size(),_fp);
		_fp?fclose(_fp):void();
		}
		if(_flag == MODE_DEBUG)
		{
		OutputDebugStringA(_str.c_str());
		}
		if(_flag == MODE_BUILDER)
		{
			fwrite(_str.data(),1,_str.size(),_fp);
		}
		
	}
	mylog & operator << (const wchar_t* s)
	{
		_str+=wide2ansi(s);
		return *this;
	}
	mylog & operator << (int x)
	{
		char buf[16]={};
		sprintf(buf,"%d",x);
		_str+=buf;
		return *this;
	}
	FILE * _fp;
	int _flag;
	std::string _str;
};
#define MYLOG  mylog()
#define FYLOG  mylog("c:\\temp\\mylog.txt")
int _tmain(int argc, _TCHAR* argv[])
{
	const char* s = "hello";
	std::wstring wstr = ansi2wide(s);
	std::wstring xx=L"xx";
	std::wstring xxx = wstr+xx;
	MYLOG <<"hello:" << 100 << 200 << 300 << L"gaga\r\n" ;
	MYLOG <<"hello:" << L"gaga\r\n" ;
	mkdir("c:\\temp");
	FYLOG <<"hello:" << 100 << 200 << 300 << L"gaga\r\n" ;
	FYLOG <<"hello:" << L"gaga\r\n" ;
	logBuilder lb("c:\\temp\\xxx.txt");
	mylog log(lb);
	log<<"test:"<<L"haha:"<<100<<200<<"\r\n";
	
	return 0;
}


  • 就這樣吧,如果輸出爲OutpuptDebugString 則使用MODE_DEBUG
  • 如果使用文件,使用 MODE_FILE ,每次都關閉一下文件,效率極低
  • 使用 MODE_BUILDER 則在開始打開文件,最後關閉。
  • 如果多線程使用,則要加入臨界區
  • 如果要支持自己定義的類,則要實現全局的 mylog & operator << (mylog & log ,type value); 這樣的函數(type 是自己的類或者結構體.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章