vindyz
vindyz

Reputation: 1101

How to create function like printf variable argument

I was looking to implement an api like printf for my logging. It should be similar to calling printf. For example:

persistent_log(LogType0, "This is buffered writing %d", i);

I looked into variable argument stuff , but it seems I need to know the number & type of arguments there. so I need more help in that regard.

Upvotes: 21

Views: 23347

Answers (3)

Nathan
Nathan

Reputation: 137

This is an old question, but here is my simplified base solution that exactly mimics printf and should be expandable to other more specific uses, it's basically a generalized version of Michael Mior's answer:

#include <stdarg.h>

void print(const char* fmt, ...)
{
    va_list arg;
    va_start(arg, fmt);

    vprintf(fmt, arg); 
    //vprintf can be replaced with vsprintf (for sprintf behavior) 
    //or any other printf function preceded by a v

    va_end(arg);
}

(This seems to work in c++ as well)

Upvotes: 3

Michael Mior
Michael Mior

Reputation: 28762

Here's an excerpt from a past project that I found to work well for me. Some initialization steps are of course missing. The key here is the vfprintf function which will handle the details of printing the various arguments.

void _proxy_log(log_level_t level, const char *fmt, ...)
    __attribute__((format (printf, 2, 3)));

#define proxy_log(level, fmt, ...) _proxy_log(level, fmt"\n", ##__VA_ARGS__)

void _proxy_log(log_level_t level, const char *fmt, ...) {
    va_list arg;
    FILE *log_file = (level == LOG_ERROR) ? err_log : info_log;

    /* Check if the message should be logged */
    if (level > log_level)
        return;

    /* Write the error message */
    va_start(arg, fmt);
    vfprintf(log_file, fmt, arg);
    va_end(arg);

#ifdef DEBUG
    fflush(log_file);
    fsync(fileno(log_file));
#endif
}

Upvotes: 28

Related Questions