如何编写一个vfprintf包装器,为格式说明符添加前缀并将新格式说明符传递给C89中的vfprintf?

时间:2015-08-10 03:22:05

标签: c argument-passing c89

我正在尝试编写vfprintf函数的包装器,但要求我要为格式说明符添加前缀,然后将新的格式说明符传递给vfprintf

现在我不知道如何做到这一点,但我已经在下面的代码中抓住了我的意图。

#include <stdio.h>
#include <stdarg.h>

void err(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    vfprintf(stderr, "foo: error:" format, args);
    va_end(args);
}

int main()
{
    err("%s: %d\n", "Transaction failed with error code", 42);
    return 0;
}

您可以在上面的代码中看到,我想在"foo: error"前加上格式说明符,然后将其传递给vprintf。当然,这段代码会导致编译时错误,因为此代码无效。它只是抓住了我想要实现的目标。

lone@debian:~/lab/c$ gcc -std=c89 -Wall -Wextra -pedantic vfprintf-wrapper.c 
vfprintf-wrapper.c: In function ‘err’:
vfprintf-wrapper.c:8:36: error: expected ‘)’ before ‘format’
     vfprintf(stderr, "foo: error:" format, args);
                                    ^
vfprintf-wrapper.c:8:5: error: too few arguments to function ‘vfprintf’
     vfprintf(stderr, "foo: error:" format, args);
     ^

你能帮我正确编写这段代码吗?

1 个答案:

答案 0 :(得分:4)

您的伪代码vfprintf(stderr, "foo: error:" format, args);应为:

fprintf(stderr, "foo: error:");
vfprintf(stderr, format, args);

您似乎表示要避免“额外”fprintf来电。如果是这样,那么你可以这样做:

char *fail = malloc(sizeof "foo: error:" + strlen(format));
if ( !fail )
    exit(EXIT_FAILURE);
strcpy(fail, "foo: error:");
strcat(fail, format);

vfprintf(stderr, fail, args);

free(fail);

虽然这会浪费时间和资源。