[英]C/C++ va_arg - Is there a way to skip an argument?
我想为sprintf()添加功能。 具体来说,我希望能够将自己的POD数据类型传递给它,但我不确定如何执行此操作。
据说,如果你创建了va_list,你可以把它传递给vsprintf()并让它为你做艰苦的工作 - 但我仍然需要访问va_list,并在将va_list传递给vsprintf()之前自己提取项目。
例如,假设以下代码:
struct mypod {
int somedata;
}; // just for example, you know
// somewhere else in the code...
mypod mp;
mp.somedata = 5325;
my_sprintf(myChrPtr, "%z", mp);
新的%z代码对应于我的新数据类型。
我知道只有指针和POD结构才能通过,这没什么大不了的。 我想知道,如果我到达va_list的末尾(通过使用va_arg()获取args然后将其传递给vsprintf())会发生什么?
谢谢!
制作两个va_list
并只使用一个来做你需要做的事情,然后将另一个传递给vsprintf
或其他:
va_list l1 = va_start(final_arg);
va_list l2 = va_start(final_arg);
// do stuff with l1 and l2 will be unaffected
vsprintf(/*using l2*/);
请记住,va_list实际上只是指向堆栈上某个位置的指针(我猜这是特定于实现的,但这就是我来自哪里)。 va_arg
返回被转换为指定类型的va_list
指向的东西,并通过sizeof(thetype)
递增指针。 因此,如果你得到两个指针并保持一个而不修改它,你可以将它传递给另一个函数。
我希望我没有误解这个问题。
鉴于必须以正确的顺序调用va_arg
并使用正确的类型来确保正确的行为,我认为你必须在处理你关心的部分并将其余的部分传递给vsprintf
使用fmt
零碎:
void
mysprintf(char *dst, char *fmt, ...)
{
char *p = fmt;
va_list va;
va_start(va, fmt);
do {
char *q = strchr(p, '|');
if (q) {
/* really should take const char *fmt and not write on it like this... */
*q++ = '\0';
}
dst += vsprintf(dst, p, va); /* let vsprintf do a subset */
if (q) {
dst += sprintf(dst, "%d", va_arg(va, int)); /* consume 1 int */
}
p = q;
} while (p);
va_end(va);
}
strcpy(fmt, "%s|%s|%s"); /* mutable fmt */
mysprintf(buf, fmt, "hello", 7, "world", 8, "!");
在我的例子中,我刚刚接受了|
就像%d
但是附加%...
转义的真实例子将会复杂得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.