基于Sylvain的回答,这里有一个简单的实现,asprintf()
因为vasprintf()
你需要一个,你通常最终也需要另一个。而且,鉴于va_copy()
C99 中的宏,它很容易asprintf()
在vasprintf()
. 实际上,在编写 varargs 函数时,将它们成对使用通常很有帮助,一个使用省略号表示法,一个使用va_list
参数代替省略号,您可以根据后者轻松实现前者。
这导致代码:
int vasprintf(char **ret, const char *format, va_list args)
{
va_list copy;
va_copy(copy, args);
/* Make sure it is determinate, despite manuals indicating otherwise */
*ret = NULL;
int count = vsnprintf(NULL, 0, format, args);
if (count >= 0)
{
char *buffer = malloc(count + 1);
if (buffer == NULL)
count = -1;
else if ((count = vsnprintf(buffer, count + 1, format, copy)) < 0)
free(buffer);
else
*ret = buffer;
}
va_end(copy); // Each va_start() or va_copy() needs a va_end()
return count;
}
int asprintf(char **ret, const char *format, ...)
{
va_list args;
va_start(args, format);
int count = vasprintf(ret, format, args);
va_end(args);
return(count);
}
在没有提供这些函数的系统中使用这些函数的棘手部分是决定函数应该在哪里声明。理想情况下,它们会在 中<stdio.h>
,但是您不需要编写它们。所以,你必须有一些其他的头文件,<stdio.h>
如果它们没有在<stdio.h>
. 而且,理想情况下,代码应该半自动地检测到这一点。也许标题是"missing.h"
, 并且包含(部分):
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdarg.h>
#ifndef HAVE_ASPRINTF
extern int asprintf(char **ret, const char *format, ...);
extern int vasprintf(char **ret, const char *format, va_list args);
#endif /* HAVE_ASPRINTF */
另外,请注意asprintf()的这个手册页说,如果出现错误,指针中的返回值是不确定的。其他手册页,包括问题中引用的手册页,表明它在错误时显式设置为 NULL。C 标准委员会文件 ( n1337.pdf ) 没有指定内存不足的错误行为。
- 如果使用 asprintf(),不要假设函数失败时指针已初始化。
- 如果实现 asprintf(),请确保指针在错误时设置为 null 以提供确定性行为。