Search code examples
cprintfc-preprocessorvariadicvariadic-macros

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?


Solution

  • 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.