我正在用C语言编写一个函数,该函数接受可变数量的参数。
我认为
因此,我向您求助,StackOverflow用户。是否有任何更好的方法提供C89兼容性,或者没有
size_t myprintf(char *fmt, ...);
到目前为止,一切都很顺利。我决定按照“正确的方式™”来做事,并制作一个接受可变参数的版本和另一个接受va_list
的版本。
size_t myprintf(char *fmt, ...);
size_t myvprintf(char *fmt, va_list args);
这并不难。除了my_vprintf()
需要将其args
发送到两个不同的函数(首先是使用长度为0的snprintf()
确定我们需要多少空间,然后在分配了那么多空间后是sprintf()
)。我使用va_copy
来实现这一点。
size_t myvprintf(char *fmt, va_list args)
{
va_list args2;
va_copy(args, args2);
// do stuff with args2
va_end(args2);
// do more stuff with args
}
这一切看起来都很好,但是C99的实现有些欠缺。如果可能的话,我希望我的代码也能在C89中运行,并且在尽可能多的编译器和平台上运行。我目前在#include <stddef.h>
之后但在任何代码之前添加了以下内容:
#ifndef va_copy
# ifdef __va_copy
# define va_copy(a,b) __va_copy(a,b)
# else /* !__va_copy */
# define va_copy(a,b) ((a)=(b))
# endif /* __va_copy */
#endif /* va_copy */
我认为
((a)=(b))
是不可靠的,应该使用memcpy()
或类似的函数,但这仅限于“如果您不支持C99,我希望它能够工作”,而不是“如果您不支持C99,无需担心”(这正是我想要的)。有没有好的方法来解决这个限制?我看到了一些解决方案- va_list
函数吃掉一个参数并递归,传递两次va_list
,以便生成两个单独的副本等- 但我不知道它们的效果如何(如果我只想调用vsnprintf()
,递归解决方案将无法很好地解决问题,对吗?)。因此,我向您求助,StackOverflow用户。是否有任何更好的方法提供C89兼容性,或者没有
va_copy
和__va_copy
的用户(尽管少之又少)只能接受它并承担?