我有一个围绕 printf 功能的包装器:
enum Color {
Black, White
};
void my_printf(char *fmt, ...)
{
char big_buffer[1024];
/* do some stuff */
va_list myargs;
va_start(myargs, fmt);
int ret = vsprintf(big_buffer, fmt, myargs);
/* process arguments that were not processed by vprintf */
va_end(myargs);
}
/* example of usage */
my_printf("%d %ld %y %y\n", 3, 3L, Black, White); /* %y - knows how to printf colors */
fmt 可以包含标准的 printf 说明符和我的自定义说明符。在 fmt 字符串中,自定义说明符始终位于标准说明符之后。要处理标准说明符,我使用vprintf,然后处理未由 vprintf 处理的参数。目前,我必须手动解析 fmt 字符串,并根据 fmt 中的说明符执行多个 va_arg ,但它容易出错。有可能使用一些能够为我做多个 va_arg 的功能吗?
我尝试在 vprintf 之后使用 myargs 。它似乎工作。但据我所知,将 va_list 对象传递给可能使用 va_arg 的其他函数后,这是非法的。
注意:我知道在这种特殊情况下,我可以在调用 my_printf 之前将颜色转换为字符串并使用%s < fmt 中的/ strong>说明符,而不是%y 。这只是一个简化的例子。所以我的想法是我有自定义说明符,我必须在 my_printf 中处理它们。所以不需要提出我不应该使用自定义说明符的答案。
答案 0 :(得分:2)
是否可以使用一些能为我做多个va_arg的函数?
不,没有适合多个va_arg
的标准功能。如果vsprintf(big_buffer, fmt, myargs);
遇到无效的打印说明符,则结果为未定义的行为。 (UB)。
目前,我必须手动解析
fmt
字符串并执行多个va_arg
,具体取决于fmt
中的说明符,但它容易出错
这是你必须要做的。
考虑使用您手动解析fmt
字符串的代码发布问题,我们可以帮助减少错误。
替代方案:代码可以调用不同的print(...)
方法,从而无需显式编码的类型说明符。 Example
答案 1 :(得分:2)
您是否考虑过下载并使用GNU implementation of printf?正如您在示例中向我们展示的那样,它包含(相对)方便customize printf方式。