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 是自己的类或者结构体.