Forward an invocation of a variadic function in C

前端 未结 12 2583
悲哀的现实
悲哀的现实 2020-11-22 06:41

In C, is it possible to forward the invocation of a variadic function? As in,

int my_printf(char *fmt, ...) {
    fprintf(stderr, \"Calling printf with fmt %         


        
12条回答
  •  梦如初夏
    2020-11-22 07:21

    Not sure if this helps to answer OP's question since I do not know why the restriction for using a helper function akin to vfprintf in the wrapper function applies. I think the key problem here is that forwarding the variadic argument list without interpreting them is difficult. What is possible, is to perform the formatting (using a helper function akin to vfprintf: vsnprintf) and forward the formatted output to the wrapped function with variadic arguments (i.e. not modifying the definition of the wrapped function). So, here we go:

    #include 
    #include 
    
    int my_printf(char *fmt, ...)
    {
        if (fmt == NULL) {
            /* Invalid format pointer */
            return -1;
        } else {
            va_list args;
            int len;
    
            /* Initialize a variable argument list */
            va_start(args, fmt);
    
            /* Get length of format including arguments */
            len = vsnprintf(NULL, 0, fmt, args);
    
            /* End using variable argument list */
            va_end(args);
            
            if (len < 0) {
                /* vsnprintf failed */
                return -1;
            } else {
                /* Declare a character buffer for the formatted string */
                char formatted[len + 1];
    
                /* Initialize a variable argument list */
                va_start(args, fmt);
                
                /* Write the formatted output */
                vsnprintf(formatted, sizeof(formatted), fmt, args);
                
                /* End using variable argument list */
                va_end(args);
    
                /* Call the wrapped function using the formatted output and return */
                fprintf(stderr, "Calling printf with fmt %s", fmt);
                return printf("%s", formatted);
            }
        }
    }
    
    int main()
    {
        /* Expected output: Test
         * Expected error: Calling printf with fmt Test
         */
        my_printf("Test\n");
        //printf("Test\n");
    
        /* Expected output: Test
         * Expected error: Calling printf with fmt %s
         */
        my_printf("%s\n", "Test");
        //printf("%s\n", "Test");
    
        /* Expected output: %s
         * Expected error: Calling printf with fmt %s
         */
        my_printf("%s\n", "%s");
        //printf("%s\n", "%s");
    
        return 0;
    }
    

    I came across this solution here.

    Editted: fixed mistakes pointed out by egmont

提交回复
热议问题