如何向 va_list 添加参数
How to add an argument to a va_list
我有以下代码:
int __dmasprintf (char **s, const char *format, ...) {
char buf[512];
va_list arg;
int ret;
va_start(arg,format);
ret = vsprintf(buf, format, arg);
va_end(arg);
*s = strdup(buf);
if (*s == NULL) return -1;
return 0;
}
我想在调用 vsprintf()
之前向 va_list
arg
添加一个参数,因为我的 format
在末尾包含 1 个额外的参数。
如何向 va_list
arg
添加参数(例如 char * myarg
)?
或者是否可以传递 vsprintf()
自定义列表?
你不能。
您要么需要进行两次 vsprintf
(肯定是 vsnprintf
?)调用,要么用可变参数宏替换您的函数,例如
#define __dmasprintf(S, FMT, ...) ( \
(*S = do_dmasprintf(FMT, __VA_ARGS__, my_arg)) == NULL ? -1 : 0)
char *do__dmasprintf (const char *format, ...) {
char buf[512];
va_list arg;
int ret;
va_start(arg,format);
ret = vsnprintf(buf, sizeof(buf), format, arg);
va_end(arg);
char *s = strdup(buf);
return s;
}
备注:
- 我用
vsnprintf
替换了 vsprintf
。没有理由在这里(或几乎任何其他地方)使用前者
- 你忽略
ret
。你应该吗?
- 我保持宏参数布局与原来的类似,但由于
__VA_ARGS__
必须是一个或多个参数(不能为空),这意味着在 [ 之后至少需要一个参数=17=]。如果你想在它后面允许零参数,只需完全删除 FMT
参数。
不幸的是,没有直接的方法可以做到这一点。这是有原因的:stdarg 宏获取最后一个已知参数在堆栈中的地址,然后直接迭代堆栈。
如果你可以使用宏,@Useless 提供了一个很好的解决方案 - 请注意,当你传递变量时,宏可能会产生副作用 - 或 post - 固定为 ++
或 --
.
如果你想避免宏,你将不得不编写你自己的 vsprintf 变体。没问题,只需找到 C stdlib 的源代码(GNU libc 可能是一个不错的起点)并且勇敢一点......希望你可以使用宏!
我有以下代码:
int __dmasprintf (char **s, const char *format, ...) {
char buf[512];
va_list arg;
int ret;
va_start(arg,format);
ret = vsprintf(buf, format, arg);
va_end(arg);
*s = strdup(buf);
if (*s == NULL) return -1;
return 0;
}
我想在调用 vsprintf()
之前向 va_list
arg
添加一个参数,因为我的 format
在末尾包含 1 个额外的参数。
如何向 va_list
arg
添加参数(例如 char * myarg
)?
或者是否可以传递 vsprintf()
自定义列表?
你不能。
您要么需要进行两次 vsprintf
(肯定是 vsnprintf
?)调用,要么用可变参数宏替换您的函数,例如
#define __dmasprintf(S, FMT, ...) ( \
(*S = do_dmasprintf(FMT, __VA_ARGS__, my_arg)) == NULL ? -1 : 0)
char *do__dmasprintf (const char *format, ...) {
char buf[512];
va_list arg;
int ret;
va_start(arg,format);
ret = vsnprintf(buf, sizeof(buf), format, arg);
va_end(arg);
char *s = strdup(buf);
return s;
}
备注:
- 我用
vsnprintf
替换了vsprintf
。没有理由在这里(或几乎任何其他地方)使用前者 - 你忽略
ret
。你应该吗? - 我保持宏参数布局与原来的类似,但由于
__VA_ARGS__
必须是一个或多个参数(不能为空),这意味着在 [ 之后至少需要一个参数=17=]。如果你想在它后面允许零参数,只需完全删除FMT
参数。
不幸的是,没有直接的方法可以做到这一点。这是有原因的:stdarg 宏获取最后一个已知参数在堆栈中的地址,然后直接迭代堆栈。
如果你可以使用宏,@Useless 提供了一个很好的解决方案 - 请注意,当你传递变量时,宏可能会产生副作用 - 或 post - 固定为 ++
或 --
.
如果你想避免宏,你将不得不编写你自己的 vsprintf 变体。没问题,只需找到 C stdlib 的源代码(GNU libc 可能是一个不错的起点)并且勇敢一点......希望你可以使用宏!