__VA_ARGS__用法

__VA_ARGS__用法

2023年7月10日发(作者:)

__VA_ARGS__⽤法⾃定义调试信息的输出  调试信息的输出⽅法有很多种, 例如直接⽤printf, 或者出错时使⽤perror, fprintf等将信息直接打印到终端上, 在Qt上⾯⼀般使⽤qDebug,⽽守护进程则⼀般是使⽤syslog将调试信息输出到⽇志⽂件中等等...  使⽤标准的⽅法打印调试信息有时候不是很⽅便, 例如Qt编程, 在调试已有的代码时, 我想在打印调试信息的地⽅, 把代码位置也打印出来以⽅便定位错误, 或者需要在调试信息前⾯加⼀个前辍, 好⽅便在调试信息太多的时候可以⽤grep过滤⼀下, 仅显⽰本模块的调试信息, 这时就需要⼀个⼀个地修改已有的qDebug, 使其成为以下形式:

  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__宏在预编译时会替换成当前的函数名称  有了以上这⼏个宏,特别是有了__VA_ARGS__ ,调试信息的输出就变得灵活多了。

  有时,我们想把调试信息输出到屏幕上,⽽有时则⼜想把它输出到⼀个⽂件中,可参考下⾯的例⼦://debug.c#include

#include//开启下⾯的宏表⽰程序运⾏在调试版本, 否则为发⾏版本, 这⾥假设只有调试版本才输出调试信息

#define _DEBUG#ifdef _DEBUG

//开启下⾯的宏就把调试信息输出到⽂件,注释即输出到终端

#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:%dn", 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:%dn", moduleName, ##__VA_ARGS__, __FILE__, __LINE__ );

#endif //end for #ifdef DEBUG_TO_FILE #else

//发⾏版本,什么也不做

#define printDebugMsg(moduleName, format, ...)

#endif //end for #ifdef _DEBUGint main(int argc, char** argv)

{

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}; va_list arg;

va_start (arg, format);

vsnprintf(buffer, DEBUG_BUFFER_MAX_LENGTH, format, arg);

va_end (arg); printf( "%s", buffer );

}

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688986473a191845.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信