可变参数宏 #if DEBUG 调试输出debug,发行版本不输出
来源:互联网 发布:树洞软件 编辑:程序博客网 时间:2024/06/06 16:32
想输出:
#if DEBUG
#define GODebugLog(frmt, ...) {NSLog((frmt), ##__VA_ARGS__);}
#else
#define GODebugLog(frmt, ...)
#endif
}
qDebug( "[模块名称] 调试信息 File:%s, Line:%d", __FILE__, __LINE__ );
一个比较简单的方法就是自已定义一个打印调试信息的宏, 然后替换原来的
例子, 我用WiFi表示当前代码的模块名称,我要求在模块中的所有调试信息前面均带有[WiFi]前辍,这样我就能方便地只需使用命令行 | grep "\[WiFi\]"来过滤掉来自其它模块的调试信息了:
#define qWiFiDebug(format, ...) qDebug("[WiFi] "format" File:%s, Line:%d, Function:%s", ##__VA_ARGS__, __FILE__, __LINE__ , __FUNCTION__);
上面的宏是使用qDebug输出调试信息,在非Qt的程序中也可以改为printf,守护进程则可以改为syslog等等... 其中,决窍其实就是这几个宏 ##__VA_ARGS__, __FILE__, __LINE__ 和__FUNCTION__,下面介绍一下这几个宏:
1) __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错, 你可以试试。
2) __FILE__ 宏在预编译时会替换成当前的源文件名
3) __LINE__宏在预编译时会替换成当前的行号
4) __FUNCTION__宏在预编译时会替换成当前的函数名称
2) __FILE__ 宏在预编译时会替换成当前的源文件名
3) __LINE__宏在预编译时会替换成当前的行号
4) __FUNCTION__宏在预编译时会替换成当前的函数名称
有了以上这几个宏,特别是有了__VA_ARGS__ ,调试信息的输出就变得灵活多了。
//开启下面的宏表示程序运行在调试版本, 否则为发行版本, 这里假设只有调试版本才输出调试信息
#if DEBUG
#define GODebugLog(frmt, ...) {NSLog((frmt), ##__VA_ARGS__);}
#else
#define GODebugLog(frmt, ...)
#endif
#if DEBUG
设置下用户名和密码,免得每次都输入
#if DEBUG
UserID = "abc@abc.com";
Password = "123456";
#endif
设置下登陆状态,免得每次都要登陆
#if DEBUG
IsLogin = true;
#elif
......
#endif
//开启下面的宏就把调试信息输出到文件,注释即输出到终端
#define DEBUG_TO_FILE
#ifdef DEBUG_TO_FILE
//调试信息输出到以下文件
#define DEBUG_FILE "/tmp/debugmsg"
//调试信息的缓冲长度
#define DEBUG_BUFFER_MAX 4096
//将调试信息输出到文件中
#define printDebugMsg(moduleName, format, ...) {\
char buffer[DEBUG_BUFFER_MAX+1]={0};\
snprintf( buffer, DEBUG_BUFFER_MAX \
, "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );\
FILE* fd = fopen(DEBUG_FILE, "a");\
if ( fd != NULL ) {\
fwrite( buffer, strlen(buffer), 1, fd );\
fflush( fd );\
fclose( fd );\
}\
}
#else
//将调试信息输出到终端
#define printDebugMsg(moduleName, format, ...) \
printf( "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );
#endif //end for #ifdef DEBUG_TO_FILE
#else
//发行版本,什么也不做
#define printDebugMsg(moduleName, format, ...)
#endif //end for #ifdef _DEBUG
#if DEBUG
UserID = "abc@abc.com";
Password = "123456";
#endif
设置下登陆状态,免得每次都要登陆
#if DEBUG
IsLogin = true;
#elif
......
#endif
//开启下面的宏就把调试信息输出到文件,注释即输出到终端
#define DEBUG_TO_FILE
#ifdef DEBUG_TO_FILE
//调试信息输出到以下文件
#define DEBUG_FILE "/tmp/debugmsg"
//调试信息的缓冲长度
#define DEBUG_BUFFER_MAX 4096
//将调试信息输出到文件中
#define printDebugMsg(moduleName, format, ...) {\
char buffer[DEBUG_BUFFER_MAX+1]={0};\
snprintf( buffer, DEBUG_BUFFER_MAX \
, "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );\
FILE* fd = fopen(DEBUG_FILE, "a");\
if ( fd != NULL ) {\
fwrite( buffer, strlen(buffer), 1, fd );\
fflush( fd );\
fclose( fd );\
}\
}
#else
//将调试信息输出到终端
#define printDebugMsg(moduleName, format, ...) \
printf( "[%s] "format" File:%s, Line:%d\n", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );
#endif //end for #ifdef DEBUG_TO_FILE
#else
//发行版本,什么也不做
#define printDebugMsg(moduleName, format, ...)
#endif //end for #ifdef _DEBUG
int main(int argc, char** argv)
{
int data = 999;
printDebugMsg( "TestProgram", "data = %d", data );
return 0;
}
{
int data = 999;
printDebugMsg( "TestProgram", "data = %d", data );
return 0;
}
上面也说了,只有支持C99规范的gcc编译器才有__VA_ARGS__这个宏,如果不是gcc编译器,或者所用的gcc编译器版本不支持__VA_ARGS__宏怎么办? 可参考下面的代码片段,我们换一种做法,可先将可变参数转换成字符串后,再进行输出即可:
void printDebugMsg( const char* format, ...)
{
char buffer[DEBUG_BUFFER_MAX_LENGTH + 1]={0};
{
char buffer[DEBUG_BUFFER_MAX_LENGTH + 1]={0};
va_list arg;
va_start (arg, format);
vsnprintf(buffer, DEBUG_BUFFER_MAX_LENGTH, format, arg);
va_end (arg);
printf( "%s", buffer );va_start (arg, format);
vsnprintf(buffer, DEBUG_BUFFER_MAX_LENGTH, format, arg);
va_end (arg);
}
0 0
- 可变参数宏 #if DEBUG 调试输出debug,发行版本不输出
- Debug调试输出函数
- DeBug调试输出
- chrome浏览器debug版本调试并且输出调试信息
- chrome浏览器debug版本调试并且输出调试信息
- Debug模式应用程序输出Debug调试信息
- Debug 输出字符串 调试信息
- 使用宏定义打开/关闭调试输出(debug版本与release版本互相切换)
- 可变参数宏输出调试信息
- 重写Android Log的输出,只在debug的时候输出,release 的版本不输出
- VS2010输出debug版本dll和lib
- MFC debug 调试信息的输出
- C# debug调试信息打印及输出
- debug 输出 以及宏定义
- debug 输出 以及宏定义
- 条件编译debug与可变参数宏
- 可变参数应用在调试信息输出
- 安卓Studio学习笔记---gradle自定义BuildConfig.DEBUG实现在调试输出Log,正式的时候不输出Log
- hdu 3182 Hamburger Magi(状压dp)
- 实现HI-LO猜游戏
- 【NOIP2013提高组day1】火柴排队
- linux下socket连接下的心跳机制
- 蘑菇街 App 的组件化之路
- 可变参数宏 #if DEBUG 调试输出debug,发行版本不输出
- java的动态代理和静态代理
- 设计模式之装饰模式
- Ubuntu12.04安装RabbitMQ服务器
- Codeforces 645C Enduring Exodus【二分】
- 第3周项目3-输出星号图(2)
- Java中private , public , protected 几个关键字
- socket api
- IntelliJ 创建main函数快捷