是否有一个等同于snprintf的va_list,其中包含一个变量参数的va_list?我试图实现两个功能:
char * __HYP format_cstring(const char * format, ...);
chat * __HYP format_cstringv(const char * format, var_list args);
但我不确定如何将snprintf
应用于这种情况。像这样的东西(注意问号):
char * __HYP format_cstring(const char * format, ...)
{
int size = snprintf(NULL, 0, format, ??);
char * buffer = (char *)malloc(size * sizeof(char));
if (snprintf(buffer, size, format, ??) < 0) {
free(buffer);
return NULL;
}
return buffer;
}
它的format_cstringv
对应物呢?
答案 0 :(得分:1)
以下是我最终如何做到这一点:
// .h
char * sformat(const char * format, ...) __attribute__((format (printf, 1, 2)));
char * vsformat(const char * format, va_list args) __attribute__((format (printf, 1, 0)));
实施:
char * __HYP sformat(const char * format, ...)
{
char * buffer;
va_list args;
va_start(args, format);
buffer = __HYP vsformat(format, args);
va_end(args);
return buffer;
}
char * __HYP vsformat(const char * format, va_list args)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
int size = vsnprintf(NULL, 0, format, args);
if (size <= 0) {
return NULL;
}
char * buffer = new char[size + 1];
if (buffer == NULL) {
return NULL;
}
if (vsnprintf(buffer, static_cast<size_t>(size), format, args) <= 0) {
free(buffer);
return NULL;
}
#pragma GCC diagnostic pop
return buffer;
}
几年后,我一直在发现我对C ++的健忘状况。
答案 1 :(得分:-2)
您对自1980年以来UNOS和DECUS上存在的%r格式感兴趣。
请参阅:http://austingroupbugs.net/view.php?id=800
在libschily中有一个超过30年的实现,请参阅:`http://sourceforge.net/projects/schilytools/files/和尚未发布的实现,作为Solaris上libc的增强。
%r允许任何基于printf()的函数由包装函数调用,然后该函数可以提供完整的printf()特性集。
%r有两个参数:
1)格式字符串
2)va_list类型参数
它需要对名为va_arg_list()
的vararg宏进行增强,类似于和出于同样的原因,为什么Sun / Solaris必须在20世纪90年代早期引入va_copy()
才能实现%n$
以下是一些示例代码:
int
error(const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = js_fprintf(stderr, "%r", fmt, args);
va_end(args);
return (ret);
}