Question

My environment: Xcode5, iOS, Objective-C/Objective-C++ mix.

I am trying to figure out what causes the next problem. I am writing my own logging function:

int _me_log(const char *fmt, ...) {

va_list args;
va_start(args, fmt);

char *c = va_arg(args, char *);

char *message = NULL;

printf(fmt, args);

int n = asprintf(&message, fmt, args);

if (n != -1 && message != NULL) {
 //do something with 'message' like writing to file, etc.
 UPDATE:
//we need to handle memory created for 'message' storage.
free(message); 
}
va_end(args);

return n;

}

Then I call it like this:

_me_log("socket %s did open", "Socket: 0x1fd1c880");

And instead of correct output socket Socket: 0x1fd1c880 did open I get some gibberish like this socket \\323\331/ did open in this line printf(fmt, args);.

If I call it this way printf("%s", c); I get correct results.

I have googled several implementations (this or this ) of logging functions and functions which pass variable parameters and it seems that I do everything correctly.

Could you please suggest me what I'm doing wrong?

Was it helpful?

Solution

You've got the right idea to use va_list here, but if you work with va_list you should use vasprintf instead of asprintf:

int _me_log(const char *fmt, ...)
{
    va_list args;
    char *message = NULL;
    int n;

    va_start(args, fmt);
    n = vasprintf(&message, fmt, args);

    if (n != -1 && message != NULL) {
        // ... use message ...
    }
    free(message);
    va_end(args);

    return n;
}

For every routine of the printf family, there is a variant that takes a va_list instead of the variadic argument ... and whose name is prefixed with the letter v, for example:

int printf(const char *format, ...);
int vprintf(const char *format, va_list ap);

These routines exist so you can write you own (non-macro) wrapper for xprintf.

OTHER TIPS

Seems like a very complicated implementation. Try:

int _me_log(const char *fmt, ...) {
    int ret = 0;
    va_list va;
    va_start(va, fmt);
    ret = vprintf(fmt, va);
    va_end(va);

    putc('\n', stdout);
    return ret;
}

But, of course, that is no different from printf(), except for forcing a newline.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top