如何计算格式化 wchar 数组所需的大小,`CRT_SECURE` 方式?

How to calculate the size needed for formated wchar array, `CRT_SECURE` way?

我需要计算格式化的 wchar 数组所需的大小。
考虑以下代码:

wchar_t* Format(const wchar_t* format, ...)
{
    va_list args;
    va_start(args, format);

    wchar_t *w = NULL;
    int len = _vsnwprintf(NULL, 0, format, args) + 1;            // <------ Error
    if (len > 0)
    {
        w = new wchar_t[len];
        w[0] = 0;
        _vsnwprintf_s(w, len, len, format, args);
    }
    va_end(args);

    return w;
}

如果 _CRT_SECURE_NO_WARNINGS 打开,上面的代码工作,如果没有,错误说:

'_vsnwprintf': This function or variable may be unsafe. Consider using _vsnwprintf_s instead.

但我无法设法使用 _vsnwprintf_s 来计算 wchar 缓冲区所需的大小。

以下是我的尝试:

int len = _vsnwprintf_s(NULL, 0, 0, format, args); // return 1

// debug assertion failed: string != NULL && DstSizeInWords > 0
int len = _vsnwprintf_s(NULL, 0, INT_MAX, format, args);

// debug assertion failed: string != NULL && DstSizeInWords > 0
int len = _vsnwprintf_s(NULL, INT_MAX, 0, format, args);

// debug assertion failed: string != NULL && DstSizeInWords > 0
int len = _vsnwprintf_s(NULL, INT_MAX, INT_MAX, format, args);

其他功能:_snwprintf给出_CRT_SECURE错误并且_snwprintf_s_vsnwprintf_s具有相同的效果

问题:

虽然我打开 _CRT_SECURE_NO_WARNINGS 还不错,但我想知道如何计算格式化 wchar 数组所需的大小,CRT_SECURE 方式?请注意,它必须接受 va_list 作为协议。

您应该能够使用 _vscwprintf:

获得所需的缓冲区大小
_Check_return_ _Ret_z_ wchar_t *
Format(_Printf_format_string_ _In_z_ wchar_t const * const psz_format, ...)
{
    size_t formatted_string_length;
    va_list args;
    {
        va_start(args, psz_format);
        int const result(::_vscwprintf(psz_format, args));
        va_end(args);
        if(-1 == result)
        {
            ::abort();
        }
        assert(0 <= result);
        formatted_string_length = static_cast< size_t >(result);
    }
    size_t const buffer_size(formatted_string_length + 1u);
    wchar_t * const p_buffer(new wchar_t[buffer_size]);
    {
        va_start(args, psz_format);
        int const result(::_vsnwprintf_s(p_buffer, buffer_size, formatted_string_length, psz_format, args));
        va_end(args);
        if(-1 == result)
        {
            ::abort();
        }
        assert(0 <= result);
        assert(static_cast< size_t >(result) == formatted_string_length);
        assert(L'[=10=]' == p_buffer[formatted_string_length]);
    }
    return p_buffer;
}