2

我的环境:Xcode5、iOS、Objective-C/Objective-C++ 混合。

我试图找出导致下一个问题的原因。我正在编写自己的日志记录功能:

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;

}

然后我这样称呼它:

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

而不是正确的输出,我在这一行socket Socket: 0x1fd1c880 did open得到了一些像这样的乱码。socket \\323\331/ did openprintf(fmt, args);

如果我这样称呼它,printf("%s", c);我会得到正确的结果。

我已经用谷歌搜索了几个日志函数和传递变量参数的函数的实现(thisthis),似乎我做的一切都是正确的。

你能告诉我我做错了什么吗?

4

2 回答 2

2

您在这里使用的想法是正确的va_list,但是如果您与您一起工作,则va_list应该使用vasprintf而不是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;
}

对于该printf系列的每个例程,都有一个变体,它采用 ava_list而不是可变参数...,其名称以字母 为前缀v,例如:

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

这些例程存在,因此您可以为xprintf.

于 2013-11-12T14:02:43.477 回答
1

似乎是一个非常复杂的实现。尝试:

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;
}

printf()但是,当然,除了强制换行之外,这与 没有什么不同。

于 2013-11-12T13:55:38.823 回答