一、
1、在验证程序时,往往需要使用printf输出现在的状态,以达到检测当前程序的作用
printf("app start\n");
2、在printf使用较多时,会出现来回注释和解除注释,此时我们可以使用另一种方式,使用define来进行定义。如果我们测试结束之后,可以将OPEN_LOG的数值改为0,这样就不会在打印
#define OPEN_LOG 1
#ifdef OPEN_LOG
printf("app start1\n");
#endif
#ifdef OPEN_LOG
printf("app start2\n");
#endif
#ifdef OPEN_LOG
printf("app start3\n");
#endif
二、
1、打印数据若出现多组,也可以使用函数的形式
void text01(int a,int b)
{
printf("a=%d b=%d\n", a, b);
}
2、若希望打印的函数的参数是一个可变参,可以打印不定长度的数值
void text02(char fmt,...)
{
va_list arg1;
va_start(arg1, fmt);
printf("%d \n", va_arg(arg1, int));
printf("%d \n", va_arg(arg1, int));
va_end(arg1);
}
void main()
{
int a = 10,b = 20;
text02("", a, b,9);
}
此时打印出的数据分别为10和20,根据text02里输出两个数值,输出了在main中输入的前两个数值。
3、将以上函数整理
#include <stdio.h>
#include <stdarg.h>
#define OPEN_LOG 1
void EM_LOG(const char *fmt,...)
{
va_list arg;
va_start(arg, fmt);
char buf[vsnprintf(NULL, 0, fmt, arg)+1]; //可变参的数据长度
vsnprintf(buf, sizeof(buf), fmt, arg);
#ifdef OPEN_LOG
printf("%s\n", buf);
#endif
va_end(arg);
}
void main()
{
int a = 10, b = 20;
char c = 'a';
EM_LOG("app start");
EM_LOG("a=%d", a);
EM_LOG("b=%d", b);
EM_LOG("a=%d b=%d", a, b);
}
4、日志打印也可以分等级,即在某某时候,把低等级的屏蔽掉,留下高等级的
#include <stdio.h>
#include <stdarg.h>
#define OPEN_LOG 1
#define LOG_LEVEL LOG_DEBUG
typedef enum
{
LOG_DEBUG = 0,
LOG_INFO,
LOG_WARN,
LOG_ERROR,
} E_LOGLEVEL;
char * EM_LOGLevelGet(const int level)
{
if(level==LOG_DEBUG){
return "DEBUG";
}else if(level==LOG_INFO){
return "INFO";
}else if(level==LOG_WARN){
return "WARN";
}else if(level==LOG_ERROR){
return "ERROR";
}
}
void EM_LOG(const int level,const char *fmt,...)
{
#ifdef OPEN_LOG
va_list arg;
va_start(arg, fmt);
char buf[vsnprintf(NULL, 0, fmt, arg)+1]; //可变参的数据长度
vsnprintf(buf, sizeof(buf), fmt, arg);
va_end(arg);
if(level>=LOG_LEVEL)
printf("%s\n", buf);
#endif
}
void main()
{
int a = 10, b = 20;
EM_LOG(LOG_DEBUG,"app start");
EM_LOG(LOG_INFO,"a=%d", a);
EM_LOG(LOG_WARN,"b=%d", b);
EM_LOG(LOG_ERROR,"a=%d b=%d", a, b);
}
此时更改#define LOG_LEVEL LOG_DEBUG即可更改输出的数值,根据enum中的设置,
如果设置为LOG_DEBUG,则输出四个
如果设置为LOG_INFO,则输出后三个
如果设置为LOG_WARN,则输出后两个
如果设置为LOG_ERROR,则输出最后一个
5、最后进行完善,并将文件分为log.c和log.h文件
#include "log.h"
#include <stdio.h>
#include <stdarg.h>
char * EM_LOGLevelGet(const int level)
{
if(level==LOG_DEBUG){
return "DEBUG";
}else if(level==LOG_INFO){
return "INFO";
}else if(level==LOG_WARN){
return "WARN";
}else if(level==LOG_ERROR){
return "ERROR";
}
}
void EM_LOG(const int level,const char* fun,const int line,const char *fmt,...)
{
#ifdef OPEN_LOG
va_list arg;
va_start(arg, fmt);
char buf[vsnprintf(NULL, 0, fmt, arg)+1]; //可变参的数据长度
vsnprintf(buf, sizeof(buf), fmt, arg);
va_end(arg);
if(level>=LOG_LEVEL)
printf("[%s] [%s %d]%s\n", EM_LOGLevelGet(level), fun, line,buf);
#endif
}
#define EMLog(level,fmt...) EM_LOG(level,__FUNCTION__,__LINE__,fmt)
#ifndef _LOG_H
#define _LOG_H
#define OPEN_LOG 1
#define LOG_LEVEL LOG_DEBUG
#define LOG_SAVE 1
typedef enum
{
LOG_DEBUG = 0,
LOG_INFO,
LOG_WARN,
LOG_ERROR,
} E_LOGLEVEL;
#define EMLog(level,fmt...) EM_LOG(level,__FUNCTION__,__LINE__,fmt)
char *EM_LOGLevelGet(const int level);
void EM_LOG(const int level, const char *fun, const int line, const char *fmt, ...);
#endif
main
void main()
{
int a = 10, b = 20;
EMLog(LOG_DEBUG, "app start");
EMLog(LOG_INFO, "A=%d", a);
EMLog(LOG_WARN, "app LOG_WARN");
EMLog(LOG_ERROR, "app LPG_ERROR");
}