lgm42
lgm42

Reputation: 621

passing multiple arguments in parameter C++ without using va_list

I have a function format like :

std::string format(const char* szFormat,...)
{
    std::string stringResult;
char c;

va_list args;
va_start(args, szFormat);

//we estimate the size to malloc
    int nSize = vsnprintf(&c, 1, szFormat, args);

va_end(args);

char *str = (char *)malloc(sizeof(char) * (nSize + 1));

    //we must make va_start again otherwize vsnprintf won't work    
va_list args2;
va_start(args2, szFormat);
vsnprintf(str, nSize + 1, szFormat, args2);
va_end (args2);

std::string result(str);
free(str);

return result;
}

I have a function display like :

std::string display(const char* szFormat,...)
{
}

which must call format().

I can't make va_start in display() function and change signature of format function by

std::string format(const char * szFormat, va_list &arg_ptr)

because my format command must run va_start many times.

(once to estimate the length of the targeted string and once to create the real string).

Have you got an idea ?

EDIT :

For those who want fully functionnal solution thanks to Brian :

static std::string format(const char * szFormat, va_list &arg_ptr)
{
    std::string stringResult;
    char c;

    va_list args2;
    va_copy(args2, arg_ptr);

    int nSize = vsnprintf(&c, 1, szFormat, arg_ptr);
    char *str = (char *)malloc(sizeof(char) * (nSize + 1));

    vsnprintf(str, nSize + 1, szFormat, args2);

    std::string result(str);
    free(str);

    return result;
}

static std::string format(const char * szFormat,...)
{
    va_list args;
    va_start(args, szFormat);
    std::string result = format(szFormat, args);
    va_end(args);
    return result;
}

Upvotes: 2

Views: 660

Answers (1)

Brian Bi
Brian Bi

Reputation: 119562

Change the signature of format(). Then use the va_copy macro to make a copy of the va_list in format(), so you can call va_start once on each copy.

Upvotes: 2

Related Questions