简体   繁体   中英

How to use Variadic macros with fprintf

I am trying to print logs into a file by writing macros. My macro looks like as shown below:

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

And I plan to call LOG in the following format:

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

But when I compile I get the error

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

Can someone please explain where I am going wrong?

First of all you have to wrap you macro into a do-while loop, so it will be handled with expressions correctly.

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

Then you have to make sure that fopen() call succeeds and that you close the file after usage.

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

Then you include the print in the full macro.

#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 )

The call is in the form:

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

where you have to input at least one correct optional parameter, with the corresponding flag in the string.

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

Multiple issues

  1. You never fclose F.
  2. __FILE__ is a string.
  3. If you want to be able to call it without parameters __VA_ARGS__ must go at the end...
  4. ... or use this little hack:

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

( ##__VA_ARGS__ is a GCC extension that removes the preceding comma if there are no args).

Also check out this answer about "custom" printf-like functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM