我目前正在使用我的C文件中声明的以下宏。
#define COMMON_Print(...) printf (__VA_ARGS__)
现在该调用工作得很好,但事实证明我需要能够创建一个看起来像这样的C函数:
void COMMON_Print(...)
{
printf (__VA_ARGS__);
}
因此该功能不起作用,我收到错误
“错误:未定义标识符__VA_ARGS __”
我的项目的复杂性需要有一个函数,因为它是一个接口......那么我如何获取参数...并将它们传递给printf函数?或者更好的是我做错了什么?
谢谢!
答案 0 :(得分:43)
每个?printf
函数都有一个相应的v?printf
函数,它执行相同的操作,但需要va_list
,一个可变参数列表。
#include <stdio.h>
#include <stdarg.h>
void COMMON_Print(char *format, ...)
{
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
旁注:请注意,va_start
将...
之前的最后一个参数的名称作为参数。 va_start
是一个宏,它执行一些基于堆栈的魔法来检索变量参数,它需要最后一个固定参数的地址来执行此操作。
因此,必须至少有一个固定的参数,以便您可以将其传递给va_start
。这就是我添加format
参数而不是坚持使用更简单的COMMON_Print(...)
声明的原因。
请参阅: http://www.cplusplus.com/reference/clibrary/cstdio/vprintf/
答案 1 :(得分:19)
__VA_ARGS__
仅适用于宏;可变函数是相当不同的。您需要使用va_arg
中的va_start
,va_end
和stdarg.h
来处理它们。
首先,您的函数至少需要一个命名参数,例如:
void COMMON_Print(const char* fmt, ...)
然后,您可以定义va_list
并使用va_start
进行设置:
va_list args;
va_start(args, fmt);
// your code here
va_end(args);
现在您可以使用args
来访问参数;调用va_arg(args, TYPE)
将返回下一个可变参数,所以你可以继续调用它,直到你读完所有的参数。
如果您只是想致电printf
,则会有一个名为vprintf
的printf变体直接接收va_list
:
vprintf(fmt, args);
没有简单的方法可以从另一个中调用一个可变参数函数;你需要vprintf
之类的东西,它需要整个va_list
答案 2 :(得分:5)
__VA_ARGS__
仅适用于宏。
不能直接将参数的变量数链接到另一个函数。相反,你必须 传递一个va_list,你正在调用的函数必须带一个va_list。幸运的是,有一种printf可以做到这一点,你的功能必须这样写:
void COMMON_Print(char *format,...)
{
va_list args;
va_begin(args,format);
vsprintf(format,args);
va_end(args);
}
答案 3 :(得分:3)
您正在寻找的是Ellipsis运营商。