C语言刚学完的随笔。
1.学会在头文件中用宏定义调试语句
#define SPIDER_LOG(level, format, ...) do{
if (level >= g_conf->log_level) {
time_t now = time(NULL);
char msg[MAX_MESG_LEN];
char buf[32];
sprintf(msg, format, ##__VA_ARGS__);
strftime(buf, sizeof(buf), "%Y%m%d %H:%M:%S", localtime(&now));
fprintf(stdout, "[%s] [%s] %s ", buf, LOG_STR[level], msg);
fflush(stdout);
}
if (level == SPIDER_LEVEL_ERROR) {
exit(-1);
}
} while(0)
2、关于格式书写的原因
1: 因为宏语句不能有 (这样就会变成两句,但是写成代码段的形式, 则使用来连接两句话,显得会很好看)
2: 之所以使用do while语句是因为通常定义的宏,在引用的时候后面需要加一个分号(;)但是一段正常的代码EG if(a=0) sentence; if () sentence; 我们习惯已经加了分号。为了避免出错,我们引用do while语句,这样可以自然而然在主函数中加分号,而这个语句不需要循环,所以是do while(0)即只执行一次。
3、level具体用法:
类似于printf的调试语句,根据level的不同,可以在配置文件中对于这个宏进行打开和关闭。
其中level这个位置可以写
# 0 DEBUG
# 1 INFO
# 2 WARN
# 3 ERROR
# 4 CRIT
然后
format是输入输出格式就是写“THIS IS %d”这种东西,后面的...是变参
4、##__VA_ARGS__,sprintf,strftime详解
eg:
#define debug(...) printf(__VA_ARGS__)
sprintf(msg, format, ##__VA_ARGS__);
在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。
缺省号代表一个可以变化的参数表。使用保留名 __VA_ARGS__ 把参数传递给宏。当宏的调用展开时,实际的参数就传递给 printf()了。
strftime,是一种计算机函数,strftime() 函数根据区域设置格式化本地时间/日期,函数的功能将时间格式化,或者说格式化一个时间字符串。
函数原型:我们可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下:
size_t strftime(
char *strDest,
size_t maxsize,
const char *format,
const struct tm *timeptr
);
函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。
格式命令列在下面,它们是区分大小写的。(具体去 man)
%a 星期几的简写
%A 星期几的全称
%b 月份的简写
%B 月份的全称
等等
语法
strftime(format,timestamp)参数 描述
format 可选。规定如何返回结果。
timestamp 可选。