vc写日志

机器圣手 2010-09-29 12:49:27
那为大虾指导用vc6写日志,主要用于记录串口输出
...全文
589 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
MYNAMELIULI 2010-09-30
  • 打赏
  • 举报
回复
利用一个类模板就好了~
controstr 2010-09-30
  • 打赏
  • 举报
回复
使用方法


// 初始化日志文件
CLoger::Instantiate(LOG_TOFILE, 100, "log\\log.xml"); // 注意整个程序初始化一次就行了

// 调用方法
PrintDbg( LL_DEBUG, HFCLOG("你要输出的日志ID=%d,name=%s\n"), __LINE__, 1, "aaa");
controstr 2010-09-30
  • 打赏
  • 举报
回复
log.cpp


#include "Log.h"
#include <time.h>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#endif

#ifndef MAX_PATH
#define MAX_PATH 256
#endif

#define LINE_BUFFER_SIZE 102400


//CLog m_log( CLog::ToConsole, 100, "log\\log.log", false );

CLog::CLog( int mode, int level, char * filename, bool append )
: m_lastLogTime(0),
m_filename(NULL),
m_tofile(false),
m_todebug(false),
m_toconsole(false),
m_append(false),
m_hlogfile(NULL)
{
SetFile( filename, append );
SetMode(mode);
SetLevel(level);

char * path = __FILE__;
char * ptr = strrchr( path, '\\' );
if ( ptr != NULL )
{
m_prefix_len = ptr + 1 - path;
m_prefix = new char[m_prefix_len+1];
memcpy( m_prefix, path, m_prefix_len );
m_prefix[m_prefix_len] = '\0';
}
}

CLog::~CLog(void)
{
if ( m_filename != NULL )
free(m_filename);
if ( m_prefix != NULL )
delete [] m_prefix;
CloseFile();
}

void CLog::SetMode( int mode )
{
m_mode = mode;

if ( m_mode & LOG_TODEBUG )
m_todebug = true;
else
m_todebug = false;

if ( m_mode & LOG_TOFILE )
{
if ( !m_tofile )
OpenFile();
}else
{
CloseFile();
m_tofile = false;
}

if ( m_mode & LOG_TOCONSOLE )
{
if ( !m_toconsole )
AllocConsole();
m_toconsole = true;
}else
{
//FreeConsole();
m_toconsole = false;
}

}
int CLog::GetMode( void )
{
return m_mode;
}

void CLog::SetLevel( int level )
{
m_level = level;
}
int CLog::GetLevel( void )
{
return m_level;
}

void CLog::SetStyle( int style )
{
m_style = style;
}
int CLog::GetStyle( void )
{
return m_style;
}


// 设置文件名及追加方式
void CLog::SetFile( const char * filename, bool append )
{
CloseFile();
if ( m_filename != NULL )
free(m_filename);
m_filename = strdup(filename);
m_append = append;

if ( m_tofile )
OpenFile();
}

void CLog::OpenFile()
{
if ( m_filename == NULL )
{
m_todebug = true;
m_tofile = false;
return;
}
m_tofile = true;
m_lastLogTime = 0;

// 如果不为追加在后面,则将原日志文件备份
if ( !m_append )
{
char backupfilename[MAX_PATH];
memset( backupfilename, 0x0, MAX_PATH );
char * ptr = strrchr( m_filename, '.' );
if ( ptr != NULL )
{
int len = (int)(ptr - m_filename);
memcpy( backupfilename, m_filename, len );
time_t t = time(NULL);
tm *local = localtime(&t);
sprintf( backupfilename+len, " %04d-%02d-%02d %02d%02d%02d%s", local->tm_year+1900, local->tm_mon+1, local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec, ptr);
::remove(backupfilename);
::rename(m_filename, backupfilename);
}
}
m_hlogfile = ::fopen(m_filename, "w+");
if ( m_hlogfile == NULL )
{
m_todebug = true;
m_tofile = false;
return;
}

::fseek(m_hlogfile, 0, SEEK_END);
}

void CLog::CloseFile()
{
if ( m_hlogfile != NULL )
{
::fclose(m_hlogfile);
}
m_hlogfile = NULL;

}

void CLog::ReallyPrint( char * format, va_list ap )
{
time_t current = time(NULL);
// 显示当前时间
if ( current != m_lastLogTime )
{
m_lastLogTime = current;

char time_str[32];
strncpy( time_str, ctime(&m_lastLogTime), 24 );
if ( m_style & TIME_INLINE )
//strcpy( &time_str[24], " - " );
strcpy( &time_str[24], "\n" );
else
strcpy( &time_str[24], "\n" );
ReallyPrintLine(time_str);
}

char * format_ptr = format;

char line[LINE_BUFFER_SIZE] = {0};
int len = _vsnprintf( line, LINE_BUFFER_SIZE-2, format_ptr, ap );
//line[LINE_BUFFER_SIZE-2] = '\0';
//int len = (int)strlen(line);
if ( len > 0 && len <= LINE_BUFFER_SIZE-2 && line[len-1] == '\n' )
{
line[len] = '\0';
}
if ( m_style & (NO_FILE_NAMES | NO_TAB_SEPARATOR) )
{
char * ptr = strchr(line, '\t');
if ( ptr != NULL )
{
// 不显示文件名
if ( m_style & NO_FILE_NAMES )
{
ReallyPrintLine(ptr+1);
return;
}else if ( m_style & NO_TAB_SEPARATOR )
*ptr = ' ';
}
}
ReallyPrintLine(line);
}
void CLog::ReallyPrintLine( char * line )
{
mutex_lock l(handle_mutex);

if ( m_todebug )
OutputDebugStringA(line);

if ( m_toconsole )
{
#if _WIN32
DWORD bytes;
WriteConsoleA( GetStdHandle(STD_OUTPUT_HANDLE), line, (DWORD)strlen(line), &bytes, NULL );
#endif
}

if ( m_tofile && (m_hlogfile != NULL) )
{
if ( ::fwrite(line, 1, strlen(line), m_hlogfile) > 0 )
fflush(m_hlogfile);
}
}


////////////////////////////////////////////////////////////////////
CLog *CLoger::itsLog = NULL;
CLoger::CLoger()
{
}
CLoger::~CLoger()
{
UnInstantiate();
}

bool CLoger::Instantiate(int mode, int level, char * filename, bool append)
{
if ( itsLog )
{
delete itsLog;
}

itsLog = new CLog(mode, level, filename, append);
return true;
}
void CLoger::UnInstantiate()
{
if ( itsLog )
{
delete itsLog;
}

itsLog = NULL;
}

CLog &CLoger::GetLog()
{
if ( !itsLog )
{
Instantiate(LOG_TOFILE, LL_MEMORYERROR, "log\\log.log", false);
}

return *itsLog;
}
controstr 2010-09-30
  • 打赏
  • 举报
回复
log.h

#if !defined(_hf_log_file_include_132B60A_DC56A5_h)
#define _hf_log_file_include_132B60A_DC56A5_h

#pragma once

#include <stdarg.h>
#include <stdio.h>
#include "../omnithread/mutex.h"

#define HFCLOG(s) (__FILE__ ":" __FUNCTION__ ":%i\t" s)
#pragma warning(disable:4996)

#if defined(_USRDLL)
#ifndef COMMONDLLEXPORT
#ifdef COMMON_EXPORTS
#define COMMONDLLEXPORT __declspec(dllexport)
#else
#define COMMONDLLEXPORT __declspec(dllimport)
#endif
#endif
#else
#define COMMONDLLEXPORT
#endif

#define LOG_TODEBUG 1 // 调试
#define LOG_TOFILE 2 // 写文件
#define LOG_TOCONSOLE 4 // 控制台

class COMMONDLLEXPORT CLog
{
public:
CLog( int mode = LOG_TODEBUG, int level = 1, char * filename = NULL, bool append = false );
~CLog(void);

void SetMode( int mode );
int GetMode( void );
void SetLevel( int level );
int GetLevel( void );
void SetStyle( int style );
int GetStyle( void );

void SetFile( const char * filename, bool append = false );

inline void Print( int level, char * format, ... )
{
if ( level > m_level ) return;

va_list ap;
va_start(ap, format);
ReallyPrint( format, ap );
va_end(ap);
}
private:
void OpenFile();
void CloseFile();

void ReallyPrint( char * format, va_list ap );
void ReallyPrintLine( char * line );
public:

enum Style
{
TIME_INLINE = 0x01,
NO_FILE_NAMES = 0x02,
NO_TAB_SEPARATOR = 0x04
};
private:
bool m_tofile, m_todebug, m_toconsole, m_append;
int m_level;
int m_mode;
int m_style;
FILE *m_hlogfile;
char *m_filename;

char *m_prefix; // 路径
size_t m_prefix_len; // 路径长度

time_t m_lastLogTime;
omni_mutex handle_mutex;
};

class COMMONDLLEXPORT CLoger
{
public:
CLoger();
~CLoger();

static bool Instantiate(int mode = LOG_TODEBUG, int level = 4, char * filename = NULL, bool append = false);
static void UnInstantiate();
static CLog &GetLog();
private:
static CLog *itsLog;
};


// 不记录目志文件
#define LL_NONE 0
// 初始化程序,启动服务
#define LL_STATE 1
// 程序退出,或释放或关闭服务或关闭程序
#define LL_END 1
// 初始化失败
#define LL_INTERR 1
// 操作数据库错误
#define LL_DBERROR 3
// 内存出错
#define LL_MEMORYERROR 4
// socket 错误
#define LL_SOCKERR 7

// 内部警告
#define LL_INTWARN 8
// 网络数据封包
#define LL_NETPACK 8
// 内部信息
#define LL_INTINFO 9
// socket 信息
#define LL_SOCKINFO 10

// 调试信息
#define LL_DEBUG 50


#define PrintDbg CLoger::GetLog().Print

#endif // _hf_log_file_include_132B60A_DC56A5_h
jacky_qiu 2010-09-29
  • 打赏
  • 举报
回复
不好意思,上面的代码有问题,我重新贴一下:


/****************************************************************************
ftrace() 函数
功能:将要监视的状况写入应用程序事件日志,方便了解程序的运行状况。
操作:在StdAfx.h加入以下代码(或者放在一个独立的头文件中),之后在需要的地方调用ftrace()函数就可以监视变量
说明:
1.希望所有的ftrace函数无效,只需要注释掉“#define WRITE_DATA” 就可以了。
2.所有输出的数据都会保存在程序目录下的"AppLog.txt"文件,数据以追加的方式存入文件。
3.更详细介绍请访问:http://hi.baidu.com/qiujiejia/blog/item/e43943187fc1f90e34fa4176.html
4.由于在下水平有限,若有错误,还望海涵。若有问题,请email我:qiujiejia@gmail.com
****************************************************************************/

//注释掉这一句会使所有ftrace()函数无效
#define WRITE_DATA

#ifdef WRITE_DATA

#include <sstream>
#include <string>

//设置类成为通用版本
#ifdef _UNICODE
#define tstring wstring
#define tostringstream wostringstream
#else
#define tstring string
#define tostringstream ostringstream
#endif

class WRITE_DATA_TO_FILE
{
private:
FILE* fp;
public:
WRITE_DATA_TO_FILE(char* FileName) {fp=fopen(FileName,"a+");}
~WRITE_DATA_TO_FILE(){ fclose(fp); }

void PrintString(TCHAR* OutputStr,int nMax)
{
#ifdef _UNICODE
//先进行转换
char* buff = new char[nMax*2+1];
memset(buff,0,nMax*2+1);
setlocale(LC_ALL,".936");
int nChars = wcstombs(buff,OutputStr,nMax*2+1);
setlocale(LC_ALL,"C");
fwrite(buff,1,nChars,fp);
delete buff;
#else
fwrite(OutputStr,1,nMax,fp);
#endif
}

template<class T> void Trace(TCHAR* ArgName,T a)
{
//ArgName就是trace() 括号里的所有东西,可能是"jacky" or _T("jacky") or TEXT("jacky")
if(*ArgName=='"') //*****************情况为 "jacky"
{
int len=_tcslen(ArgName+1);
TCHAR* p=new TCHAR[len];
_tcsncpy(p,ArgName+1,len-1);
p[len-1]='\0'; //最后一个置0
PrintString(p,len-1);
delete p;
}
else if ( *(ArgName+2)=='(' ) //******情况为 _T("jacky")
{
int len=_tcslen(ArgName+4)-1;
TCHAR* p=new TCHAR[len];
_tcsncpy(p,ArgName+4,len-1);
p[len-1]='\0'; //最后一个置0
PrintString(p,len-1);
delete p;
}
else if ( *(ArgName+4)=='(' ) //******情况为 TEXT("jacky")
{
int len=_tcslen(ArgName+6)-1;
TCHAR* p=new TCHAR[len];
_tcsncpy(p,ArgName+6,len-1);
p[len-1]='\0'; //最后一个置0
PrintString(p,len-1);
delete p;
}
else //是一个变量名称
{
PrintString(ArgName,_tcslen(ArgName)); //变量名没有分号
std::tostringstream FormatString;
FormatString<<TEXT("=")<<a;
std::tstring OutStr=FormatString.str();
PrintString((TCHAR*)OutStr.c_str(),OutStr.length());
}
}
};

//实例化一个对象
static WRITE_DATA_TO_FILE obj("AppLog.txt");

#define ftrace(X) { obj.Trace(TEXT(#X),X); obj.PrintString(_T("\n"),1); }
#define ftrace2(X,Y) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); \
obj.Trace(TEXT(#Y),Y); obj.PrintString(_T("\n"),1); }
#define ftrace3(X,Y,Z) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); \
obj.Trace(TEXT(#Y),Y); obj.PrintString(_T(" "),3); \
obj.Trace(TEXT(#Z),Z); obj.PrintString(_T("\n"),1); }
#define ftrace4(X,Y,Z,W) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); \
obj.Trace(TEXT(#Y),Y); obj.PrintString(_T(" "),3); \
obj.Trace(TEXT(#Z),Z); obj.PrintString(_T(" "),3); \
obj.Trace(TEXT(#W),W); obj.PrintString(_T("\n"),1); }
#define fTracePoint(P) ftrace2(P.x,P.y)
#define fTraceRect(X) ftrace4(X.left,X.top,X.right,X.bottom)
#define fTraceLastError(){ obj.Trace(_T("System Error Codes:"),GetLastError()); obj.PrintString(_T("\n"),1); }

#else
#define ftrace(X)
#define ftrace2(X,Y)
#define ftrace3(X,Y,Z)
#define ftrace4(X,Y,Z,W)
#define fTracePoint(P)
#define fTraceRect(X)
#define fTraceLastError()
#endif
jacky_qiu 2010-09-29
  • 打赏
  • 举报
回复
/****************************************************************************

ftrace() 函数

功能:将要监视的状况写入应用程序事件日志,方便了解程序的运行状况。

操作:在StdAfx.h加入以下代码(或者放在一个独立的头文件中),之后在需要的地方调用ftrace()函数就可以监视变量

说明:

1.希望所有的ftrace函数无效,只需要注释掉“#define WRITE_DATA” 就可以了。

2.所有输出的数据都会保存在程序目录下的"AppLog.txt"文件,数据以追加的方式存入文件。

3.更详细介绍请访问:http://hi.baidu.com/qiujiejia/blog/item/e43943187fc1f90e34fa4176.html

4.由于在下水平有限,若有错误,还望海涵。若有问题,请email我:qiujiejia@gmail.com

****************************************************************************/



//注释掉这一句会使所有ftrace()函数无效

#define WRITE_DATA



#ifdef WRITE_DATA



#include <sstream>

#include <string>



//设置类成为通用版本

#ifdef _UNICODE

#define tstring wstring

#define tostringstream wostringstream

#else

#define tstring string

#define tostringstream ostringstream

#endif



class WRITE_DATA_TO_FILE

{

private:

FILE* fp;

public:

WRITE_DATA_TO_FILE(char* FileName) {fp=fopen(FileName,"a+");}

~WRITE_DATA_TO_FILE(){ fclose(fp); }



void PrintString(TCHAR* OutputStr,int nMax)

{

#ifdef _UNICODE

//先进行转换

char* buff = new char[nMax*2+1];

memset(buff,0,nMax*2+1);

setlocale(LC_ALL,".936");

int nChars = wcstombs(buff,OutputStr,nMax*2+1);

setlocale(LC_ALL,"C");

fwrite(buff,1,nChars,fp);

delete buff;

#else

fwrite(OutputStr,1,nMax,fp);

#endif

}



template<class T> void Trace(TCHAR* ArgName,T a)

{

//ArgName就是trace() 括号里的所有东西,可能是"jacky" or _T("jacky") or TEXT("jacky")

if(*ArgName=='"') //*****************情况为 "jacky"

{

int len=_tcslen(ArgName+1);

TCHAR* p=new TCHAR[len];

_tcsncpy(p,ArgName+1,len-1);

p[len-1]='\0'; //最后一个置0

PrintString(p,len-1);

delete p;

}

else if ( *(ArgName+2)=='(' ) //******情况为 _T("jacky")

{

int len=_tcslen(ArgName+4)-1;

TCHAR* p=new TCHAR[len];

_tcsncpy(p,ArgName+4,len-1);

p[len-1]='\0'; //最后一个置0

PrintString(p,len-1);

delete p;

}

else if ( *(ArgName+4)=='(' ) //******情况为 TEXT("jacky")

{

int len=_tcslen(ArgName+6)-1;

TCHAR* p=new TCHAR[len];

_tcsncpy(p,ArgName+6,len-1);

p[len-1]='\0'; //最后一个置0

PrintString(p,len-1);

delete p;

}

else //是一个变量名称

{

PrintString(ArgName,_tcslen(ArgName)); //变量名没有分号

std::tostringstream FormatString;

FormatString<<TEXT("=")<<a;

std::tstring OutStr=FormatString.str();

PrintString((TCHAR*)OutStr.c_str(),OutStr.length());

}

}

};



//实例化一个对象

static WRITE_DATA_TO_FILE obj("AppLog.txt");



#define ftrace(X) { obj.Trace(TEXT(#X),X); obj.PrintString(_T("\n"),1); }

#define ftrace2(X,Y) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); \

obj.Trace(TEXT(#Y),Y); obj.PrintString(_T("\n"),1); }

#define ftrace3(X,Y,Z) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); \

obj.Trace(TEXT(#Y),Y); obj.PrintString(_T(" "),3); \

obj.Trace(TEXT(#Z),Z); obj.PrintString(_T("\n"),1); }

#define ftrace4(X,Y,Z,W) { obj.Trace(TEXT(#X),X); obj.PrintString(_T(" "),3); \

obj.Trace(TEXT(#Y),Y); obj.PrintString(_T(" "),3); \

obj.Trace(TEXT(#Z),Z); obj.PrintString(_T(" "),3); \

obj.Trace(TEXT(#W),W); obj.PrintString(_T("\n"),1); }

#define fTracePoint(P) ftrace2(P.x,P.y)

#define fTraceRect(X) ftrace4(X.left,X.top,X.right,X.bottom)

#define fTraceLastError(){ obj.Trace(_T("System Error Codes:"),GetLastError()); obj.PrintString(_T("\n"),1); }



#else

#define ftrace(X)

#define ftrace2(X,Y)

#define ftrace3(X,Y,Z)
austin_minny 2010-09-29
  • 打赏
  • 举报
回复
先用串口读写API将串口信息读到buffer里,然后再将buffer的内容用文件流读到日志文件里
ls2141 2010-09-29
  • 打赏
  • 举报
回复
最简单的写文本 ~~
Eleven 2010-09-29
  • 打赏
  • 举报
回复
自已定义个格式也行,写数据库也行
码侬 2010-09-29
  • 打赏
  • 举报
回复
创建一个文本文件,将串口内容写入即可。

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧