vsnprintf、_vsnprintf、_vsnprintf_l、_vsnwprintf、_vsnwprintf_lvsnprintf, _vsnprintf, _vsnprintf_l, _vsnwprintf, _vsnwprintf_l

使用指向参数列表的指针写入格式化的输出。Write formatted output using a pointer to a list of arguments. 提供这些函数的更多安全版本;请参阅 vsnprintf_s、_vsnprintf_s、_vsnprintf_s_l、_vsnwprintf_s、_vsnwprintf_s_lMore secure versions of these functions are available; see vsnprintf_s, _vsnprintf_s, _vsnprintf_s_l, _vsnwprintf_s, _vsnwprintf_s_l.

语法Syntax

int vsnprintf(
   char *buffer,
   size_t count,
   const char *format,
   va_list argptr
);
int _vsnprintf(
   char *buffer,
   size_t count,
   const char *format,
   va_list argptr
);
int _vsnprintf_l(
   char *buffer,
   size_t count,
   const char *format,
   locale_t locale,
   va_list argptr
);
int _vsnwprintf(
   wchar_t *buffer,
   size_t count,
   const wchar_t *format,
   va_list argptr
);
int _vsnwprintf_l(
   wchar_t *buffer,
   size_t count,
   const wchar_t *format,
   locale_t locale,
   va_list argptr
);
template <size_t size>
int vsnprintf(
   char (&buffer)[size],
   size_t count,
   const char *format,
   va_list argptr
); // C++ only
template <size_t size>
int _vsnprintf(
   char (&buffer)[size],
   size_t count,
   const char *format,
   va_list argptr
); // C++ only
template <size_t size>
int _vsnprintf_l(
   char (&buffer)[size],
   size_t count,
   const char *format,
   locale_t locale,
   va_list argptr
); // C++ only
template <size_t size>
int _vsnwprintf(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format,
   va_list argptr
); // C++ only
template <size_t size>
int _vsnwprintf_l(
   wchar_t (&buffer)[size],
   size_t count,
   const wchar_t *format,
   locale_t locale,
   va_list argptr
); // C++ only

参数Parameters

bufferbuffer
输出的存储位置Storage location for output.

countcount
要写入的最大字符数。Maximum number of characters to write.

formatformat
格式规范。Format specification.

argptrargptr
指向参数列表的指针。Pointer to list of arguments.

localelocale
要使用的区域设置。The locale to use.

有关更多信息,请参见 格式规范For more information, see Format Specifications.

返回值Return Value

Vsnprintf函数将返回写入的字符数,不包括终止 null 字符。The vsnprintf function returns the number of characters written, not counting the terminating null character. 如果缓冲区大小指定计数足够大,无法包含由指定的输出格式argptr的返回值vsnprintf ,则会写入,如果不包括 null 字符的字符数计数足够大。If the buffer size specified by count is not sufficiently large to contain the output specified by format and argptr, the return value of vsnprintf is the number of characters that would be written, not counting the null character, if count were sufficiently large. 如果返回的值大于计数-1,输出已被截断。If the return value is greater than count - 1, the output has been truncated. 返回值 -1 指示发生编码错误。A return value of -1 indicates that an encoding error has occurred.

同时 _vsnprintf_vsnwprintf函数将返回写入要写入的字符数是否小于或等于的字符数计数; 如果数字格式要写入的字符大于计数,则这些函数返回-1,指示输出已被截断。Both _vsnprintf and _vsnwprintf functions return the number of characters written if the number of characters to write is less than or equal to count; if the number of characters to write is greater than count, these functions return -1 indicating that output has been truncated.

不论是否写入终止 null,所有这些函数的返回值都不会将其包含在内。The value returned by all these functions does not include the terminating null, whether one is written or not. 计数为零,返回的值编写函数,不的字符数包括任何终止 null。When count is zero, the value returned is the number of characters the functions would write, not including any terminating null. 可以将此结果用于为字符串和终止 null 分配足够的缓冲区空间,然后再次调用可填充缓冲区的函数。You can use this result to allocate sufficient buffer space for the string and its terminating null, and then call the function again to fill the buffer.

如果格式NULL,或者如果缓冲区NULL计数不等于零,这些函数中所述将调用无效参数处理程序,参数验证If format is NULL, or if buffer is NULL and count is not equal to zero, these functions invoke the invalid parameter handler, as described in Parameter Validation. 如果允许执行继续,则这些函数将返回-1 并设置errnoEINVALIf execution is allowed to continue, these functions return -1 and set errno to EINVAL.

备注Remarks

其中每个函数采用指向自变量列表,然后将格式化数据,并最多写入计数指向的内存的字符缓冲区Each of these functions takes a pointer to an argument list, then formats the data, and writes up to count characters to the memory pointed to by buffer. Vsnprintf函数始终会写入一个 null 终止符,即使它截断输出。The vsnprintf function always writes a null terminator, even if it truncates the output. 使用时 _vsnprintf_vsnwprintf,缓冲区才将 null 终止仅当有空间末尾 (即,如果要写入的字符数小于计数).When using _vsnprintf and _vsnwprintf, the buffer will be null-terminated only if there is room at the end (that is, if the number of characters to write is less than count).

重要

若要防止某些类型的安全风险,确保格式不是用户定义的字符串。To prevent certain kinds of security risks, ensure that format is not a user-defined string. 有关详细信息,请参阅 避免缓冲区溢出For more information, see Avoiding Buffer Overruns.

备注

若要确保在调用时没有终止 null 的空间 _vsnprintf_vsnprintf_l_vsnwprintf_vsnwprintf_l,请确保计数严格小于缓冲区长度并将缓冲区初始化为 null 在调用函数之前。To ensure that there is room for the terminating null when calling _vsnprintf, _vsnprintf_l, _vsnwprintf and _vsnwprintf_l, be sure that count is strictly less than the buffer length and initialize the buffer to null prior to calling the function.

因为vsnprintf始终会写入终止 null计数参数可能等于缓冲区的大小。Because vsnprintf always writes the terminating null, the count parameter may be equal to the size of the buffer.

从 Visual Studio 2015 和 Windows 10 中的 UCRT 开始vsnprintf不再等同于 _vsnprintfBeginning with the UCRT in Visual Studio 2015 and Windows 10, vsnprintf is no longer identical to _vsnprintf. Vsnprintf函数遵循 C99 标准;_vnsprintf保留用于替换旧的 Visual Studio 代码向后兼容。The vsnprintf function complies with the C99 standard; _vnsprintf is retained for backward compatibility with older Visual Studio code.

使用这些函数的版本 _l后缀是相同,只不过它们使用传递而不是当前线程区域设置的区域设置参数。The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.

在 C++ 中,这些函数具有模板重载,以调用这些函数的更新、更安全副本。In C++, these functions have template overloads that invoke the newer, secure counterparts of these functions. 有关详细信息,请参阅 Secure Template OverloadsFor more information, see Secure Template Overloads.

一般文本例程映射Generic-Text Routine Mappings

TCHAR.H 例程TCHAR.H routine 未定义 _UNICODE 和 _MBCS_UNICODE & _MBCS not defined 已定义 _MBCS_MBCS defined 已定义 _UNICODE_UNICODE defined
_vsntprintf_vsntprintf _vsnprintf_vsnprintf _vsnprintf_vsnprintf _vsnwprintf_vsnwprintf
_vsntprintf_l_vsntprintf_l _vsnprintf_l_vsnprintf_l _vsnprintf_l_vsnprintf_l _vsnwprintf_l_vsnwprintf_l

要求Requirements

例程Routine 必需的标头 (C)Required header (C) 必需的标头 (C++)Required header (C++)
vsnprintf_vsnprintf_vsnprintf_lvsnprintf, _vsnprintf, _vsnprintf_l <stdio.h><stdio.h> <stdio.h> 或 <cstdio><stdio.h> or <cstdio>
_vsnwprintf_vsnwprintf_l_vsnwprintf, _vsnwprintf_l <stdio.h> 或 <wchar.h><stdio.h> or <wchar.h> <stdio.h>、<wchar.h>、<cstdio> 或 <cwchar><stdio.h>, <wchar.h>, <cstdio>, or <cwchar>

_Vsnprintf_vsnprintf_l_vsnwprintf_vsnwprintf_l函数是 Microsoft 特定。The _vsnprintf, _vsnprintf_l, _vsnwprintf and _vsnwprintf_l functions are Microsoft specific. 有关其他兼容性信息,请参阅 兼容性For additional compatibility information, see Compatibility.

示例Example

// crt_vsnwprintf.c
// compile by using: cl /W3 crt_vsnwprintf.c

// To turn off error C4996, define this symbol:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <wtypes.h>

#define BUFFCOUNT (10)

void FormatOutput(LPCWSTR formatstring, ...)
{
    int nSize = 0;
    wchar_t buff[BUFFCOUNT];
    memset(buff, 0, sizeof(buff));
    va_list args;
    va_start(args, formatstring);
    // Note: _vsnwprintf is deprecated; consider vsnwprintf_s instead
    nSize = _vsnwprintf(buff, BUFFCOUNT - 1, formatstring, args); // C4996
    wprintf(L"nSize: %d, buff: %ls\n", nSize, buff);
    va_end(args);
}

int main() {
    FormatOutput(L"%ls %ls", L"Hi", L"there");
    FormatOutput(L"%ls %ls", L"Hi", L"there!");
    FormatOutput(L"%ls %ls", L"Hi", L"there!!");
}
nSize: 8, buff: Hi there
nSize: 9, buff: Hi there!
nSize: -1, buff: Hi there!

如果使用 vsnprintf 以及窄字符串参数代替,结果会发生更改。The behavior changes if you use vsnprintf instead, along with narrow-string parameters. 计数参数可以是整个大小的缓冲区,并且返回值是将如果已写入的字符数计数是否足够大:The count parameter can be the entire size of the buffer, and the return value is the number of characters that would have been written if count was large enough:

示例Example

// crt_vsnprintf.c
// compile by using: cl /W4 crt_vsnprintf.c
#include <stdio.h>
#include <stdarg.h> // for va_list, va_start
#include <string.h> // for memset

#define BUFFCOUNT (10)

void FormatOutput(char* formatstring, ...)
{
    int nSize = 0;
    char buff[BUFFCOUNT];
    memset(buff, 0, sizeof(buff));
    va_list args;
    va_start(args, formatstring);
    nSize = vsnprintf(buff, sizeof(buff), formatstring, args);
    printf("nSize: %d, buff: %s\n", nSize, buff);
    va_end(args);
}

int main() {
    FormatOutput("%s %s", "Hi", "there");   //  8 chars + null
    FormatOutput("%s %s", "Hi", "there!");  //  9 chars + null
    FormatOutput("%s %s", "Hi", "there!!"); // 10 chars + null
}
nSize: 8, buff: Hi there
nSize: 9, buff: Hi there!
nSize: 10, buff: Hi there!

请参阅See also

流 I/OStream I/O
vprintf 函数vprintf Functions
格式规范语法:printf 和 wprintf 函数Format Specification Syntax: printf and wprintf Functions
fprintf、_fprintf_l、fwprintf、_fwprintf_lfprintf, _fprintf_l, fwprintf, _fwprintf_l
printf、_printf_l、wprintf、_wprintf_lprintf, _printf_l, wprintf, _wprintf_l
sprintf、_sprintf_l、swprintf、_swprintf_l、__swprintf_lsprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l
va_arg、va_copy、va_end、va_startva_arg, va_copy, va_end, va_start