Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何编写一个vfprintf包装器,在C89中为格式说明符添加前缀并将新的格式说明符传递给vfprintf?_C_Argument Passing_C89 - Fatal编程技术网

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

如何编写一个vfprintf包装器,在C89中为格式说明符添加前缀并将新的格式说明符传递给vfprintf?,c,argument-passing,c89,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,

我试图围绕
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;
}

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

你的伪代码
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);

尽管这会浪费时间和资源。

您的伪代码
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);


尽管那会浪费时间和资源。

看起来是一件不必要的复杂事情。为什么不在包装器内的单独语句中打印错误前缀,然后按原样调用vprintf?@n.m.这是一种非常有效的方法,但是,我想了解我所要求的是否可行以及如何做到。当然,这是可能的。只需创建一个新的格式字符串(malloc和几个strcpy就可以了)。但这可能不是最有效的解决方案。您不能做的是向varargs列表添加更多参数。
prog
是一个神秘变量,未在
err(“%s:%d\n”,“事务失败,错误代码为”,42)中说明。
ir是什么?代码试图用它做什么?看起来是一件不必要的复杂事情。为什么不在包装器内的单独语句中打印错误前缀,然后按原样调用vprintf?@n.m.这是一种非常有效的方法,但是,我想了解我所要求的是否可行以及如何做到。当然,这是可能的。只需创建一个新的格式字符串(malloc和几个strcpy就可以了)。但这可能不是最有效的解决方案。您不能做的是向varargs列表添加更多参数。
prog
是一个神秘变量,未在
err(“%s:%d\n”,“事务失败,错误代码为”,42)中说明。
ir是什么?代码试图用它做什么?如果(!fail)exit(exit_FAILURE),那么编写
似乎很遗憾-如果没有失败,则退出失败。也许更好的变量名选择是
msg_format
,或者
msgfmt
之类的。哦,您继承了问题的旧版本的
prog
名称。我认为它只是一个闯入者,或者应该作为字符串的一部分插入到格式中:
char*msgfmt=malloc(sizeof(“:error:”)+strlen(prog)+strlen(format);sprintf(msgfmt,“%s:error:%s”,prog,format);vfprintf(stderr,msgfmt,args);
(忽略
malloc()之后必要的错误检查
)@JonathanLeffler哎呀,我从他的错误消息中读到了这一点,但没有将其与实际代码匹配(正如您所说的不匹配)。是的,
fail
是指针变量的一个愚蠢名称,这是有意的:)第二种解决方案对线程更为健壮,但我希望避免使用
malloc
。有什么好主意吗?@syockit是的,用第一个。两次调用fprintf没有问题。如果您是多线程的,并且希望避免同时从写入
stderr
的不同线程交错,那么您应该使用互斥锁来包围写入
stderr
。如果(!fail)exit(exit\u FAILURE),则写入
似乎很遗憾-如果没有失败,则退出失败。也许更好的变量名选择是
msg_format
,或者
msgfmt
之类的。哦,您继承了问题的旧版本的
prog
名称。我认为它只是一个闯入者,或者应该作为字符串的一部分插入到格式中:
char*msgfmt=malloc(sizeof(“:error:”)+strlen(prog)+strlen(format);sprintf(msgfmt,“%s:error:%s”,prog,format);vfprintf(stderr,msgfmt,args);
(忽略
malloc()之后必要的错误检查
)@JonathanLeffler哎呀,我从他的错误消息中读到了这一点,但没有将其与实际代码匹配(正如您所说的不匹配)。是的,
fail
是指针变量的一个愚蠢名称,这是有意的:)第二种解决方案对线程更为健壮,但我希望避免使用
malloc
。有什么好主意吗?@syockit是的,用第一个。两次调用fprintf没有问题。如果您是多线程的,并且希望避免不同线程同时交替写入
stderr
,那么应该使用互斥锁来包围写入
stderr