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 是自己的類或者結構體.