How to use __VA_ARGS__ inside a C function instead of macro?
Possible Duplicate:
C/C++: Passing variable number of arguments around
我目前正在使用我的C文件中声明的以下宏。
1
| #define COMMON_Print(...) printf (__VA_ARGS__) |
现在该调用工作得很好,但事实证明我需要能够创建一个看起来像这样的C函数:
1 2 3 4
| void COMMON_Print (... )
{
printf (__VA_ARGS__ );
} |
因此该功能不起作用,我收到错误
"Error : undefined identifier __VA_ARGS__"
我的项目的复杂性需要有一个函数,因为它是一个接口......那么如何获取参数...并将它们传递给printf函数? 或者更好的是我做错了什么?
谢谢!
-
请参阅此stackoverflow.com/questions/205529/
每个?printf函数都有一个相应的v?printf函数,它执行相同的操作,但是接受一个va_list,一个可变参数列表。
1 2 3 4 5 6 7 8 9 10 11
| #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/
-
如果使用宏,则不需要先前的arg。 考虑这个例子:#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))从使用角度来看,这显然非常方便。
__VA_ARGS__仅适用于宏;可变函数是相当不同的。您需要使用stdarg.h中的va_start,va_arg和va_end来处理它们。
首先,您的函数至少需要一个命名参数,例如:
1
| void COMMON_Print(const char* fmt, ...) |
然后你可以定义一个va_list并使用va_start来设置它:
现在您可以使用args来访问参数;调用va_arg(args, TYPE)将返回下一个可变参数,所以你可以继续调用它,直到你读完所有的参数。
如果您只是尝试调用printf,则会有一个名为vprintf的printf变体直接接受va_list:
没有简单的方法可以从另一个函数中调用一个可变函数;你需要像vprintf那样的整个va_list
-
谢谢你的解释。 感谢他们真正帮助的帮助和解释!:)
-
只有在调用者传递NULL时,va_arg(args,TYPE)才会返回NULL。 va_arg没有默认的结束条件。 您必须传递一个标记值或知道参数传递的确切参数数量,或者计算printf格式字符串中的%数。
-
@tristopia哦,对; 我习惯在必要时传递NULL。 固定
__VA_ARGS__仅适用于宏。
将变量数量的参数链接到另一个函数不能直接完成。相反,你必须
传递一个va_list,你正在调用的函数必须带一个va_list。幸运的是有一个printf的变体,这样做,你的功能必须这样写:
1 2 3 4 5 6 7
| void COMMON_Print (char *format ,... )
{
va_list args ;
va_begin (args ,format );
vsprintf(format ,args );
va_end(args );
} |
-
非常感谢您的回复! 它确实有效! 但是有一些格式化问题正在发生,我相信我需要解决这个问题。 仅供参考,我在嵌入式设备上工作。
-
什么是vaprintf? 或者只是一个错字?
您正在寻找的是省略号算子。