如何使用fprintf的Variadic宏

时间:2014-10-10 17:40:56

标签: c printf c-preprocessor variadic variadic-macros

我正在尝试通过编写宏来将日志打印到文件中。 我的宏看起来如下所示:

#define LOG(fmt,...){\
    FILE *F;\
    F = fopen("output.txt","a");\
    fprintf(F,fmt " %s %d",__VA_ARGS__,__FILE__,__LINE__);}

我打算用以下格式调用LOG:

LOG("values are : %d %d",num1,num2);

但是当我编译时,我得到了错误

error: expected expression before ‘,’ token
     fprintf(F,fmt " %s %d",__VA_ARGS__,__FILE__,__LINE__);}

有人可以解释我哪里出错吗?

2 个答案:

答案 0 :(得分:3)

首先,你必须将宏包装到do-while循环中,这样才能正确处理表达式。

#define LOG( fmt , ... ) do{  }while(0)

然后你必须确保fopen()调用成功,并在使用后关闭文件。

FILE* f = fopen( "output.txt" , "a" ) ;
if( !f )
    break ;    //break works because you are in a loop
fclose( f ) ;    //also flushes the stream

然后在完整的宏中包含打印件。

#define LOG( fmt , ... )    \
        do{ \
            FILE* f = fopen( "output.txt" , "a" ) ; \
            if( !f )    \
                break ; \
            fprintf(f, fmt" %s %d\n",__VA_ARGS__,__FILE__,__LINE__);    \
            fclose( f ) ;   \
        }while( 0 )

电话采用以下形式:

LOG("values are : %d %d",4444,55555);

您必须输入至少一个正确的可选参数,并在字符串中包含相应的标志。

答案 1 :(得分:1)

#define LOG(fmt,...){\
    FILE *F;\
    F = fopen("output.txt","a");\
    fprintf(F,fmt " %d %d",__VA_ARGS__,__FILE__,__LINE__);}

多个问题

  1. 你永远不会fclose F。
  2. __FILE__是一个字符串。
  3. 如果您希望能够在没有参数的情况下调用它__VA_ARGS__必须在最后... {/ li>
  4. ...或者使用这个小黑客:

    #define LOG(fmt,...){\
        FILE *F;\
        F = fopen("output.txt","a");\
        fprintf(F,fmt " %s %d", ##__VA_ARGS__, __FILE__,__LINE__);}
    
  5. ##__VA_ARGS__是GCC扩展程序,如果没有args,则删除前面的逗号。)

    另请查看this answer关于" custom"类似printf的函数。