如何在vsprintf之前确定va_args的大小

时间:2019-05-20 12:31:25

标签: c++

我有一个接受可变参数的函数。我不确定编译期间参数的大小。现在,我需要将所有这些参数复制到字符数组。

在使用vsprintf之前,如何确定变量参数的大小?还是将其复制到char *是个好主意?

event(const unsigned int xyz, const char abc[], ...)
{
    //How can I determine the value of MaxLength
    char formatted_arg[MaxLength]= {'\0'};
    va_list args;
    va_start(args, format_str);
        vsprint(formatted_arg,format_str,args);
    va_end(args);
    return formatted_arg;
}

1 个答案:

答案 0 :(得分:0)

Q1。在使用vsprintf之前如何确定变量参数的大小?

您可以使用返回以下内容的vsnprintf来确定vsprintf将要写入的字符数:

  

应该写入的字符总数(不包括终止的空字节)

因此,我们可以通过以下操作找到MaxLengthvsnprintf(nullptr, 0U, format_str, args)冒出明显的风险:

  1. 这要求我们仍在va_start有效的va_endargs范围内
  2. 这是MaxLength 的长度,不包括终止的空字节

Q2。还是将其复制到char*上是个好主意?

不是。由于mentioned by DeiDei返回本地分配的数组是未定义的行为。而是考虑返回string

我还要添加一些建议:

  1. 请勿传递xyzabc这样不使用的变量,以避免编译器警告
  2. 请勿使用像format_str这样的全局变量,而应将其作为函数参数来促进函数重用

最终,您的代码应类似于:

string event(const char* format, ...) {
    va_list length_args;

    va_start(length_args, format);
    va_list result_args;

    va_copy(result_args, length_args);
    const auto length = vsnprintf(nullptr, 0U, format, length_args);
    string result(length, '\0');

    vsprintf(data(result), format, result_args);
    va_end(result_args);
    va_end(length_args);
    return result;
}

Live Example