可变参数函数(三)

2014-11-24 07:30:26 · 作者: · 浏览: 3
函数一样带有可变参数,比如
#define LOG(format, ...)fprintf(stdout, format, __VA_ARGS__)
其中,...表示参数可变,__VA_ARGS__在预处理中为实际的参数集所替换
GCC中同时支持如下的形式
#define LOG(format, args...) fprintf(stdout,format, args)
其用法和上面的基本一致,只是参数符号有变化
有一点需要注意,上述的宏定义不能省略可变参数,尽管你可以传递一个空参数,这里有必要提到"##"连接符号的用法。
"##"的作用是对token进行连接,在上例中,format、__VA_ARGS__、args即是token,
如果token为空,那么不进行连接,所以允许省略可变参数(__VA_ARGS__和args),对上述变参宏做如下修改
#define LOG(format, ...) fprintf(stdout, format, ##__VA_ARGS__)
#define LOG(format, args...) fprintf(stdout,format, ##args)
上述的变参宏定义不仅能自定义输出格式,而且配合#ifdef #else#endif在输出管理上也很方便,
比如调试时输出调试信息,正式发布时则不输出,可以这样
#ifdef DEBUG
#define LOG(format, ...) fprintf(stdout,">> "format"\n", ##__VA_ARGS__)
#else
#define LOG(format, ...)
#endif
在调试环境下,LOG宏是一个变参输出宏,以自定义的格式输出;
在发布环境下,LOG宏是一个空宏,不做任何事情。
写日志实例
#ifndef _HYC_LOG_H_
#define _HYC_LOG_H_
#include "base.h"
#include
#include
#include
//
#ifdef LOG_COUT
#define LOG_TRACE(strMsg,...) \
{\
char ch[1024] ;\
sprintf(ch,"%s %d %s %s",__FILE__,__LINE__,__DATE__,__TIME__);\
std::cout << ch << " " << minprintf(strMsg,##__VA_ARGS__)<< std::endl ;\
}
#else
//
#define LOG_TRACE(strMsg,...) \
{\
char ch[1024] ;\
sprintf(ch,"%s %d %s %s",__FILE__,__LINE__,__DATE__,__TIME__);\
char fileName[] = "huangxw.log" ; \
std::ofstream outFile(fileName,std::ios::out|std::ios::app); \
outFile << ch << " " <
outFile.close(); \
}
#endif
//
//
std::string minprintf(char *fmt, ...)
{
va_list ap; /* points to each unnamed arg in turn */
char *p, *sval;
char tVal[128] ;
int ival;
double dval;
std::string strTotal ;
va_start(ap, fmt); /* make ap point to 1st unnamed arg */
for (p = fmt; *p; p++) {
if (*p != '%') {
//putchar(*p);
strTotal += *p ;
continue;
}
switch (*++p) {
case 'd':
ival = va_arg(ap, int);
sprintf(tVal,"%d",ival);
strTotal += tVal;
break;
case 'x':
ival=va_arg(ap,int);
sprintf(tVal,"%#x",ival);
strTotal += tVal;
break;
case 'f':
dval = va_arg(ap, double);
sprintf(tVal,"%f",dval);
strTotal += tVal;
break;
case 's':
for (sval = va_arg(ap, char *);*sval; sval++)
strTotal += *sval ;
break;
default:
strTotal += *p ;
break;
}
}www.2cto.com
va_end(ap); /* clean up when done */
return strTotal;
}
#endif
test程序:
#include "../hyc_log.h"
int main()
{
LOG_TRACE("test:%d",10);
LOG_TRACE("test:%s=%d","max",10);
LOG_TRACE("test");
}