如何使用可变长度参数包装函数?
时间:2020-03-05 18:46:56 来源:igfitidea点击:
我正在寻找在C / C ++中执行此操作。
我遇到了可变长度参数,但这建议使用libffi使用Python&C解决方案。
现在,如果我想用myprintf
包装printf
函数
我所做的如下所示:
void myprintf(char* fmt, ...) { va_list args; va_start(args,fmt); printf(fmt,args); va_end(args); } int _tmain(int argc, _TCHAR* argv[]) { int a = 9; int b = 10; char v = 'C'; myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b); return 0; }
但是结果却不如预期!
This is a number: 1244780 and this is a character: h and another number: 29953463
我想念哪里了?
解决方案
回答
我们是什么意思纯C / C ++解决方案?
C运行时跨平台支持rest参数(...)。
http://msdn.microsoft.com/zh-CN/library/kb57fad8.aspx
回答
我们在使用C还是C ++?下一个C ++版本C ++ 0x将支持可变参数模板,这些模板提供了该问题的解决方案。
通过巧妙的运算符重载来实现如下语法,可以实现另一种解决方法:
void f(varargs va) { BOOST_FOREACH(varargs::iterator i, va) cout << *i << " "; } f(args = 1, 2, 3, "Hello");
为了使它起作用,必须实现类varargs
来覆盖operator =
,后者返回一个代理对象,该代理对象又覆盖`operator'。但是,据我所知,在当前的C ++中使这种变型类型安全是不可能的,因为它必须通过类型擦除来工作。
回答
我也不确定你是什么意思
在C ++中,我们使用
#include <cstdarg> #include <cstdio> class Foo { void Write(const char* pMsg, ...); }; void Foo::Write( const char* pMsg, ...) { char buffer[4096]; std::va_list arg; va_start(arg, pMsg); std::vsnprintf(buffer, 4096, pMsg, arg); va_end(arg); ... }
回答
问题是我们不能在va_args中使用'printf'。如果使用变量参数列表,则必须使用vprintf。 vprint,vsprintf,vfprintf等。(Microsoft C运行时中也有"安全"版本,可防止缓冲区溢出等)
示例工作如下:
void myprintf(char* fmt, ...) { va_list args; va_start(args,fmt); vprintf(fmt,args); va_end(args); } int _tmain(int argc, _TCHAR* argv[]) { int a = 9; int b = 10; char v = 'C'; myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b); return 0; }