1 日志打印
测试时通常需要打印日志来确定整个流程是否按需执行,而完成测试后则是不希望日志仍然被打印出来。
- 直接注释与反注释
#include <stdio.h>
void main(){
printf("starting...\n");
// TODO
printf("Process1\n");
// TODO
printf("Process2\n");
// ...
printf("end\n");
}
这种方式简单有效,但是完成测试后需要手动将每一行与日志打印相关的代码进行注释,低效、麻烦。
- 宏定义
#include <stdio.h>
#define OPEN_LOG 1
void main(){
#ifdef OPEN_LOG
printf("starting...\n");
#endif
// TODO
#ifdef OPEN_LOG
printf("Process1\n");
#endif
// TODO
#ifdef OPEN_LOG
printf("Process2\n");
#endif
// ...
#ifdef OPEN_LOG
printf("end\n");
#endif
}
这种方式通过将#define OPEN_LOG 1
注释与否即可决定日志打印的功能是否开放,但是需要在每一句日志打印开头和结尾各加上一句代码,同样也较为麻烦。
- 修改
printf()
#include <stdio.h>
#include <stdarg.h>
#define OPEN_LOG 1 // 开放日志打印功能
#define LOG_LEVEL LOG_DEBUG // 设置日志等级
// 枚举所有日志类型
typedef enum{
LOG_DEBUG = 0,
LOG_INFO,
LOG_WARNNING,
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_WARNNING){
return "WARNING";
}else if(level == LOG_ERROR){
return "ERROR";
}
return "UNKNOWN";
}
// 日志打印主函数
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); // 实现arg和fmt的链接
char buf[1 + vsnprintf(NULL, 0, fmt, arg)];
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)
int main(void){
int a = 10, b = 15;
EMLog(LOG_DEBUG, "app start..."); // 不定参数函数
return 0;
}