如何编写一个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
。