gpt4 book ai didi

c - 将单个参数列表传递给两个 v*printf() 调用

转载 作者:太空宇宙 更新时间:2023-11-04 01:13:18 25 4
gpt4 key购买 nike

考虑以下测试用例:

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

void test(char **outa, char **outb, const char* fstra, const char* fstrb, ...) {
va_list ap;

va_start(ap, fstrb);
vasprintf(&outa, fstra, ap);
vasprintf(&outb, fstrb, ap);
va_end(ap);
}

int main(void) {
char *a, *b;
test(&a, &b, "%s", " %s\n", "foo", "bar");
/* ... */
}

这里的意图是 test() 函数接受两个格式字符串和一个参数列表。第一个格式字符串应该“吃掉”它需要的所有参数,其余的参数应该用于第二个格式字符串。

因此,此处的预期结果将是 foo & bar,这就是我使用 glibc 得到的结果。但是 AFAICS 运行键盘的机器(猜测它是一些 *BSD),给出 foo & foo 我的猜测是它使用 va_copy()在参数列表上。

我想我在这里碰到了一个未定义的(而且丑陋的)行为;所以问题是:有没有一种方法可以实现双格式字符串 printf() 而无需从头开始重新实现它?有没有一种很好的方法可以在不使用 AC_RUN_IFELSE() 的情况下使用 autoconf 检查该行为?

我想一些快速扫描格式字符串以获取要使用的参数数量的方法也可以在这里使用 (+va_copy())。

最佳答案

当您调用 v*printf 之一时功能,这使用va_arg这意味着 ap 的值返回时不确定。

相关位位于7.19.6.8 The vfprintf function 部分在 C99 中,它引用了脚注:

As the functions vfprintf, vfscanf, vprintf, vscanf, vsnprintf, vsprintf, and vsscanf invoke theva_argmacro, the value ofargafter the return is indeterminate.

这在我拥有的最新 C1x 草案中也存在,所以我怀疑它不会很快改变。

没有可移植的方法来使用更高级别的 v*printf 来执行您尝试的操作尽管您可以求助于使用较低级别的东西。

标准非常明确,调用函数使用 va_argva_list 上变量使其在调用者中不确定。来自 C99 7.15 Variable Arguments <stdarg.h> :

The object ap may be passed as an argument to another function; if that function invokes the va_arg macro with parameter ap, the value of ap in the calling function is indeterminate and shall be passed to the va_end macro prior to any further reference to ap.

但是,ap的值使用 va_arg 时在单个函数中, 是确定的(否则整个变量参数处理将分崩离析)。因此,您可以使用这些较低级别的函数编写一个函数来依次处理两种格式字符串。

对于更高级别的内容(根据脚注),您需要 va_end/va_startap变量回到确定状态,不幸的是,这将重置为参数列表的开头。

我不确定您提供的示例代码简化了多少,但是,如果这接近现实,您可以通过预先组合两个格式字符串并使用它传递给 vprintf 来获得相同的结果。 ,类似于:

void test(const char* fstra, const char* fstrb, ...) {
char big_honkin_buff[1024]; // Example, don't really do this.
va_list ap;

strcpy (big_honkin_buff, fstra);
strcat (big_honkin_buff, fstrb);

va_start(ap, big_honkin_buff);
vprintf(big_honkin_buff, ap);
va_end(ap);
}

关于c - 将单个参数列表传递给两个 v*printf() 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7147700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com