我对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行为。