我想向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_arg并使用正确的类型来实现正确的行为,我认为您必须在处理您关心的部分并将其余部分传递给fmt的同时消耗vsprintf零碎的部分:

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一样,但是带有其他%...转义符的真实示例会复杂得多。

关于c++ - C/C++ va_arg-是否可以跳过参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5930370/

10-10 21:17