Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Записывает форматированные данные в строку. Доступны более безопасные версии этих функций; см_snprintf_s._snprintf_s_l
Синтаксис
int snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf(
char *buffer,
size_t count,
const char *format [,
argument] ...
);
int _snprintf_l(
char *buffer,
size_t count,
const char *format,
_locale_t locale [,
argument] ...
);
int _snwprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format [,
argument] ...
);
int _snwprintf_l(
wchar_t *buffer,
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
);
template <size_t size>
int _snprintf(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...
); // C++ only
template <size_t size>
int _snprintf_l(
char (&buffer)[size],
size_t count,
const char *format,
_locale_t locale [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format [,
argument] ...
); // C++ only
template <size_t size>
int _snwprintf_l(
wchar_t (&buffer)[size],
size_t count,
const wchar_t *format,
_locale_t locale [,
argument] ...
); // C++ only
Параметры
buffer
Место хранения выходных данных.
count
Наибольшее количество символов для записи. Для функций, которые принимают wchar_t, это максимальное количество расширенных символов для записи.
format
Строка управления форматом.
argument
Необязательные аргументы.
locale
Языковой стандарт, используемый для форматирования выходных данных.
Дополнительные сведения см. в разделе "Синтаксис спецификации формата" printf и wprintf "Функции".
Возвращаемое значение
Число символов, которые были бы записаны в буфер, если count они были проигнорированы. Число не включает завершающий NULL символ.
Допустим len , длина отформатированных строк данных, не включая завершающееся NULL.
Для всех функций, если len < countlen символы хранятся в buffer, добавляется терминатор NULL, а число записанных символов, не включая завершениеNULL, возвращается.
Расширенные версии этих функций возвращают количество записанных символов, не включая завершение NULL.
Дополнительные сведения см . в сводке по поведению.
Замечания
Начиная с UCRT в Visual Studio 2015 и Windows 10, snprintf больше не идентично _snprintf. Поведение snprintf теперь соответствует стандарту C99. Различия описаны ниже.
-
snprintfвсегда завершает буфер (даже при усечении) и возвращает общее число символов, которые были бы записаны, если буфер был достаточно велик (не подсчитывая терминатор NULL). -
_snprintfне завершает буфер, если выходные данные усечены и возвращаются-1при усечении.
Так как _snprintf при усечении не записывается пустой терминатор, он может поместить еще один символ в тот же размер буфера. Однако результирующая строка не завершается null, поэтому необходимо обрабатывать завершение самостоятельно.
-
snprintf_snprintfи семейство функций формата и храненияcountили меньше символов.buffer -
snprintfвсегда сохраняет завершающийNULLсимвол, усечение выходных данных при необходимости. - Если
snprintfвозвращает значение >count- 1, выходные данные усечены. - Семейство
_snprintfфункций добавляет только конечныйNULLсимвол, если отформатированная длина строки строго меньшеcountсимволов. - Каждый
argument(при наличии) преобразуется и выводится согласно соответствующей спецификации формата вformat. Формат состоит из обычных символов и имеет те же форму и функциональные возможности, что и аргументformatдляprintf. Если копирование производится между перекрывающимися строками, поведение не определено.
Сводка по поведению
В следующей таблице:
- Пусть
sizeOfBufferбудет размерbuffer. Если функция принимаетcharбуфер, размер находится в байтах. Если функция принимаетwchar_tбуфер, размер указывает количество 16-разрядных слов. - Допустим
len, размер отформатированных данных. Если функция принимаетcharбуфер, размер находится в байтах. Если функция принимаетwchar_tбуфер, размер указывает количество 16-разрядных слов. - Символы относятся к
charсимволам функций, которые принимаютcharбуфер, а такжеwchar_tк символам для функций, которые принимаютwchar_tбуфер. - Дополнительные сведения о обработчике недопустимых параметров см. в разделе "Проверка параметров".
| Состояние | Поведение | Возвращаемое значение | errno |
Вызывает обработчик недопустимого параметра |
|---|---|---|---|---|
| Удачное завершение | Записывает символы в буфер с помощью указанной строки формата. | Количество записанных символов. | Н/П | нет |
| Ошибка кодирования во время форматирования | Если описатель sстроки обработки , Sили Z, формат спецификации останавливается, он NULL помещается в начало буфера. |
-1 |
EILSEQ (42) |
нет |
| Ошибка кодирования во время форматирования | Если описатель символов c обработки или Cнедопустимый символ пропускается. Число записанных символов не увеличивается для пропущенного символа, а также не записывается для него никакие данные. Обработка спецификации формата продолжается после пропуска описателя с ошибкой кодирования. |
Число записанных символов, не включая завершение NULL. |
EILSEQ (42) |
нет |
buffer == NULL и count != 0. |
Если выполнение продолжается после выполнения обработчика недопустимых параметров, задает errno и возвращает отрицательное значение. |
-1 |
EINVAL (22) |
Да |
count == 0 |
Число символов, которые были бы написаны, не включая завершающийся NULL. Этот результат можно использовать для выделения достаточного пространства буфера для строки и конца NULL, а затем снова вызвать функцию для заполнения буфера. |
Н/П | нет | |
count < 0 |
Небезопасно: значение считается неподписанным, скорее всего, создает большое значение, которое приводит к перезаписи памяти, следующей за буфером. | Число записанных символов | Н/П | нет |
count < sizeOfBuffer и len <= count. |
Все данные записываются, а завершение NULL добавляется. |
Число записанных символов, не включая завершение NULL. |
Н/П | нет |
count < sizeOfBuffer и len > count. |
count-1 Первые символы записываются после конца null. |
Число символов, которые были бы записаны count , соответствовало количеству символов для выходных данных, не включая конечный элемент NULL. |
Н/П | нет |
count >= sizeOfBuffer и len < sizeOfBuffer. |
Все данные записываются с завершением NULL. |
Число записанных символов, не включая завершение NULL. |
Н/П | нет |
count >= sizeOfBuffer и len >= sizeOfBuffer. |
Небезопасно: перезаписывает память, которая следует буферу. | Число записанных символов, не включая завершение NULL. |
Н/П | нет |
format == NULL |
Данные не записываются. Если выполнение продолжается после выполнения обработчика недопустимых параметров, задает errno и возвращает отрицательное значение. |
-1 |
EINVAL (22) |
Да |
Сведения об этих и других кодах ошибок см. в разделе _doserrno, errno_sys_errlistи _sys_nerr.
Внимание
Убедитесь, что format не является строкой, определяемой пользователем.
_snprintf Так как функции не гарантируют завершение null( в частности, если возвращаемое значение countравно), убедитесь, что за ними следует код, добавляющий терминатор NULL. Дополнительные сведения см. в разделе "Избегание переполнения буфера".
Начиная с Windows 10 версии 2004 (сборка 19041), семейство функций printf выводит точно представленные числа с плавающей запятой в соответствии с правилами IEEE 754 для округления. В предыдущих версиях Windows точно представленные числа с плавающей запятой, заканчивающиеся на "5", всегда округлялись. IEEE 754 утверждает, что они должны округлиться до ближайшей даже цифры (также известной как "Округление банкира"). Например, оба printf("%1.0f", 1.5) и printf("%1.0f", 2.5) должны округлиться до 2. Ранее 1,5 округляет до 2 и 2,5 округления до 3. Это изменение влияет только на точно представленные числа. Например, 2.35 (который при представлении в памяти приближается к 2,3500000000000000008) продолжает округляется до 2,4. Округление, выполняемое этими функциями, теперь также учитывает режим округления с плавающей запятой, заданный fesetround. Ранее округление всегда выбрало FE_TONEAREST поведение. Это изменение влияет только на программы, созданные с помощью Visual Studio 2019 версии 16.2 и более поздних версий. Чтобы использовать устаревшее поведение округления с плавающей запятой, свяжите со legacy_stdio_float_rounding.objссылкой.
_snwprintf — это двухбайтовая версия _snprintf; аргументы указателя для _snwprintf представляют собой двухбайтовые строки. Обнаружение ошибок _snwprintf кодирования может отличаться от обнаружения _snprintf.
_snwprintfтак же, как swprintf, записывает выходные данные в строку вместо назначения типа FILE.
Версии этих функций, обладающие суффиксом _l , идентичны за исключением того, что они используют переданный параметр языкового стандарта вместо языкового стандарта текущего потока.
В C++эти функции имеют перегрузки шаблонов, которые вызывают более новых, более безопасных коллег. Дополнительные сведения см. в разделе "Безопасные перегрузки шаблонов".
Сопоставления подпрограмм универсального текста
Tchar.h рутина |
_UNICODE и _MBCS не определен |
_MBCS Определенные |
_UNICODE Определенные |
|---|---|---|---|
_sntprintf |
_snprintf |
_snprintf |
_snwprintf |
_sntprintf_l |
_snprintf_l |
_snprintf_l |
_snwprintf_l |
Требования
| Маршрут | Обязательный заголовок |
|---|---|
snprintf, , _snprintf_snprintf_l |
<stdio.h> |
_snwprintf, _snwprintf_l |
<stdio.h> или <wchar.h> |
Дополнительные сведения о совместимости см. в разделе Совместимость.
Пример
// crt_snprintf.c
// compile with: /W3
#include <stdio.h>
#include <stdlib.h>
#if !defined(__cplusplus)
typedef int bool;
const bool true = 1;
const bool false = 0;
#endif
#define FAIL 0 // change to 1 and see what happens
int main(void)
{
char buffer[200];
const static char s[] = "computer"
#if FAIL
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
"computercomputercomputercomputercomputercomputercomputercomputer"
#endif
;
const char c = 'l';
const int i = 35;
#if FAIL
const double fp = 1e300; // doesn't fit in the buffer
#else
const double fp = 1.7320534;
#endif
/* !subtract one to prevent "squeezing out" the terminal null! */
const int bufferSize = sizeof(buffer)/sizeof(buffer[0]) - 1;
int bufferUsed = 0;
int bufferLeft = bufferSize - bufferUsed;
bool bSuccess = true;
buffer[0] = 0;
/* Format and print various data: */
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " String: %s\n", s ); // C4996
// Note: _snprintf is deprecated; consider _snprintf_s instead
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer[bufferUsed],
bufferLeft, " Character: %c\n", c ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Integer: %d\n", i ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
bufferLeft -= perElementBufferUsed;
if (bufferLeft > 0)
{
int perElementBufferUsed = _snprintf(&buffer
[bufferUsed], bufferLeft, " Real: %f\n", fp ); // C4996
if (bSuccess = (perElementBufferUsed >= 0))
{
bufferUsed += perElementBufferUsed;
}
}
}
}
}
}
}
}
if (!bSuccess)
{
printf("%s\n", "failure");
}
else
{
/* !store null because _snprintf doesn't necessarily (if the string
* fits without the terminal null, but not with it)!
* bufferUsed might be as large as bufferSize, which normally is
* like going one element beyond a buffer, but in this case
* subtracted one from bufferSize, so we're ok.
*/
buffer[bufferUsed] = 0;
printf( "Output:\n%s\ncharacter count = %d\n", buffer, bufferUsed );
}
return EXIT_SUCCESS;
}
Output:
String: computer
Character: l
Integer: 35
Real: 1.732053
character count = 69
См. также
Потоковый ввод-вывод
sprintf, , _sprintf_lswprintf, _swprintf_l__swprintf_l
fprintf, , _fprintf_lfwprintf_fwprintf_l
printf, , _printf_lwprintf_wprintf_l
scanf, , _scanf_lwscanf_wscanf_l
sscanf, , _sscanf_lswscanf_swscanf_l
Функции vprintf