我对ansi字符串使用vsnprintf,它运行良好,仅在出错时返回-1,如果不适合缓冲区,则返回所需大小的计数。
对于宽字符串,我需要相同的函数,vsnwprintf不存在。我也尝试过_vsnwprintf,但它的行为确实不同,即使缓冲区太小,它也会返回-1,而我需要知道扩展缓冲区需要多少,但只有在有必要时,我才不想进行虚拟调用,只是为了确定需要的大小,然后才扩展缓冲区。
如果查看vsnprintf代码:

int const _Result = __stdio_common_vsprintf(
    _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR,
    _Buffer, _BufferCount, _Format, NULL, _ArgList);
return _Result < 0 ? -1 : _Result;

而VVSNWPRTNF大致有:
int const _Result = __stdio_common_vswprintf(
    _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION,
    _Buffer, _BufferCount, _Format, NULL, _ArgList);
return _Result < 0 ? -1 : _Result;

看起来只有在旗帜中的差异,我尝试手动地用cc标志调用__stdio_common_vswprintf,它完全按照我的需要运行,但是当应用程序退出时也会导致随机崩溃/冻结。所以我需要功能,也许有人知道怎么做?
P.S.I.在Windows 7上使用Microsoft Visual Studio 2017。

最佳答案

宽字符版本的vsnprintf称为vswprintf(注意:不n)。根据the documentation,它符合ISO C,因此您可以检查C标准或here中的行为。
当输出将超过缓冲区大小时,返回-1是正确的。没有截断输出的选项;您应该进行“伪调用”以检查缓冲区大小。
您总是可以将一个vswprintf调用包装在另一个具有您所需行为的函数中(进行虚拟调用,然后进行截断以适应需要,或者返回malloc'd缓冲区)。注意在UTF-16字符中间截断。
注意,MSVC的vsnprintf在某个时候改变了它的行为(2015年可能?)符合ISO C标准;可以通过调用_vsnprintf检索原始MSVC行为。

09-10 17:08