printf中的奇怪字符

时间:2013-11-12 13:48:21

标签: ios objective-c c printf objective-c++

我的环境: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 open中得到了一些像这个printf(fmt, args);一样的胡言乱语。

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

我搜索了几个实现日志函数和函数的实现(thisthis),这些函数和函数传递了可变参数,似乎我正确地做了一切。

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

2 个答案:

答案 0 :(得分: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系列的每个例程,有一个变体采用va_list而不是变量参数...,其名称前缀为v字母,例如:

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

这些例程存在,因此您可以为xprintf编写自己的(非宏)包装器。

答案 1 :(得分: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()没有区别。