【问题标题】:How to calculate the size needed for formated wchar array, `CRT_SECURE` way?如何计算格式化 wchar 数组所需的大小,`CRT SECURE` 方式?
【发布时间】:2017-12-21 20:48:21
【问题描述】:

我需要计算格式化 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':这个函数或变量可能不安全。考虑使用 _vsnwprintf_s 代替。

但我无法设法使用_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 作为ag​​rument。

【问题讨论】:

    标签: c++ format wchar-t


    【解决方案1】:

    您应该能够使用_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'\0' == p_buffer[formatted_string_length]);
        }
        return p_buffer;
    }
    

    【讨论】:

    • 正是我需要的。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    相关资源
    最近更新 更多