Namespaces
Variants

vprintf, vfprintf, vsprintf, vsnprintf, vprintf_s, vfprintf_s, vsprintf_s, vsnprintf_s

От ru.cppreference.net
< c | io
 
 
Файловый ввод/вывод
Типы и объекты
        
Функции
Доступ к файлам
(C95)
Неформатированный ввод/вывод
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

Форматированный ввод
Прямой ввод/вывод
Форматированный вывод
Позиционирование в файле
Обработка ошибок
Операции с файлами
 
Определено в заголовке <stdio.h>
int vprintf( const char* format, va_list vlist );
(1) (до C99)
int vprintf( const char* restrict format, va_list vlist );
(начиная с C99)
int vfprintf( FILE* stream, const char* format, va_list vlist );
(2) (до C99)
int vfprintf( FILE* restrict stream, const char* restrict format,
              va_list vlist );
(начиная с C99)
int vsprintf( char* buffer, const char* format, va_list vlist );
(3) (до C99)
int vsprintf( char* restrict buffer, const char* restrict format,
              va_list vlist );
(начиная с C99)
int vsnprintf( char* restrict buffer, size_t bufsz,
               const char* restrict format, va_list vlist );
(4) (начиная с C99)
int vprintf_s( const char* restrict format, va_list vlist );
(5) (начиная с C11)
int vfprintf_s( FILE* restrict stream, const char* restrict format,
                va_list vlist );
(6) (начиная с C11)
int vsprintf_s( char* restrict buffer, rsize_t bufsz,
                const char* restrict format, va_list vlist );
(7) (начиная с C11)
int vsnprintf_s( char* restrict buffer, rsize_t bufsz,
                 const char* restrict format, va_list vlist );
(8) (начиная с C11)

Загружает данные из местоположений, заданных vlist, преобразует их в строковые эквиваленты и записывает результаты в различные приёмники.

1) Записывает результаты в stdout.
2) Записывает результаты в файловый поток stream.
3) Записывает результаты в строку символов buffer.
4) Записывает результаты в строку символов buffer. Записывается не более bufsz - 1 символов. Результирующая строка будет завершена нулевым символом, если только bufsz не равно нулю. Если bufsz равно нулю, ничего не записывается, и buffer может быть нулевым указателем, однако возвращаемое значение (количество байтов, которое было бы записано без учёта завершающего нулевого символа) всё равно вычисляется и возвращается.
5-8) То же, что и (1-4), за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают функцию обработчика ограничений, установленную в данный момент:
  • спецификатор преобразования %n присутствует в format
  • любой из аргументов, соответствующих %s, является нулевым указателем
  • format или buffer является нулевым указателем
  • bufsz равно нулю или больше RSIZE_MAX
  • возникают ошибки кодирования в любом из спецификаторов преобразования строк и символов
  • (только для vsprintf_s), строка для сохранения в buffer (включая завершающий ноль) превысила бы bufsz
Как и все функции с проверкой границ, vprintf_s, vfprintf_s, vsprintf_s и vsnprintf_s гарантированно доступны только в том случае, если __STDC_LIB_EXT1__ определена реализацией и если пользователь определяет __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 перед включением <stdio.h>.

Параметры

stream - выходной файловый поток для записи
buffer - указатель на строку символов для записи
bufsz - может быть записано до bufsz - 1 символов, плюс завершающий ноль
format - указатель на строку символов, завершающуюся нулём, определяющую, как интерпретировать данные
vlist - список переменных аргументов, содержащий данные для печати.

Строка format состоит из обычных байтовых символов (кроме %), которые копируются без изменений в выходной поток, и спецификаций преобразования. Каждая спецификация преобразования имеет следующий формат:

  • вводный символ %.
  • (необязательно) один или несколько флагов, изменяющих поведение преобразования:
  • -: результат преобразования выравнивается по левому краю поля (по умолчанию выравнивается по правому краю).
  • +: знак преобразования со знаком всегда добавляется перед результатом преобразования (по умолчанию результату предшествует минус, только если он отрицательный).
  • space: если результат преобразования со знаком не начинается со знакового символа или пуст, перед результатом добавляется пробел. Игнорируется, если присутствует флаг +.
  • #: выполняется альтернативная форма преобразования. Точные эффекты см. в таблице ниже, в противном случае поведение не определено.
  • 0: для целочисленных преобразований и преобразований чисел с плавающей запятой для заполнения поля используются ведущие нули вместо символов space. Для целых чисел игнорируется, если явно указана точность. Для других преобразований использование этого флага приводит к неопределённому поведению. Игнорируется, если присутствует флаг -.
  • (необязательно) целое значение или *, которое задаёт минимальную ширину поля. Результат при необходимости дополняется символами space слева при выравнивании по правому краю или справа при выравнивании по левому краю. В случае использования * ширина задаётся дополнительным аргументом типа int, который появляется перед преобразуемым аргументом и аргументом, задающим точность, если он указан. Если значение аргумента отрицательное, это приводит к указанию флага - и положительной ширины поля (Примечание: это минимальная ширина: значение никогда не усекается).
  • (необязательно) . за которым следует целое число или *, или ни то, ни другое, что определяет точность преобразования. В случае использования * точность задаётся дополнительным аргументом типа int, который появляется перед преобразуемым аргументом, но после аргумента, задающего минимальную ширину поля, если он указан. Если значение этого аргумента отрицательное, оно игнорируется. Если не используется ни число, ни *, точность принимается равной нулю. Точные эффекты точности см. в таблице ниже.
  • (необязательно) модификатор длины, который определяет размер аргумента (в сочетании со спецификатором формата преобразования он определяет тип соответствующего аргумента).
  • спецификатор формата преобразования.

Доступны следующие спецификаторы формата:

Спецификатор
Преобразования
Пояснение Ожидаемый
Тип аргумента
Модификатор длины→ hh h нет l ll j z t L
Доступно только начиная с C99→ Да Да Да Да Да
% Выводит литерал %. Полная спецификация преобразования должна быть %%. N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

Выводит один символ.

  • Аргумент сначала преобразуется в unsigned char.
  • Если используется модификатор l, аргумент сначала преобразуется в строку символов, как если бы с помощью %ls с аргументом wchar_t[2].
N/A N/A
int
wint_t
N/A N/A N/A N/A N/A
s

Выводит строку символов.

  • Аргумент должен быть указателем на начальный элемент массива символов.
  • Точность указывает максимальное количество байтов для записи. Если Точность не указана, записываются все байты вплоть до первого нулевого терминатора, не включая его.
  • Если используется спецификатор l, аргумент должен быть указателем на начальный элемент массива wchar_t, который преобразуется в массив char, как если бы вызовом wcrtomb с нулевым состоянием преобразования.
N/A N/A
char*
wchar_t*
N/A N/A N/A N/A N/A
d
i

Преобразует целое число со знаком в десятичное представление [-]dddd.

  • Точность задаёт минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
  • Для модификатора z ожидаемый тип аргумента — версия со знаком size_t.
signed char
short
int
long
long long
intmax_t
※
ptrdiff_t
N/A
b
B (необязательно)

(C23)

Преобразует целое число без знака в двоичное представление bbbb.

  • Точность задаёт минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
  • В альтернативной реализации 0b или 0B добавляется префикс к результатам, если преобразованное значение не равно нулю.
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
uintmax_t
size_t
версия без знака ptrdiff_t
N/A
o

Преобразует целое число без знака в восьмеричное представление oooo.

  • Точность задаёт минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
  • В альтернативной реализации точность при необходимости увеличивается, чтобы записать один ведущий ноль. В этом случае, если и преобразованное значение, и точность равны 0, записывается одиночный 0.
N/A
x
X

Преобразует целое число без знака в шестнадцатеричное представление hhhh.

  • Для преобразования x используются буквы abcdef.
  • Для преобразования X используются буквы ABCDEF.
  • Точность задаёт минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
  • В альтернативной реализации 0x или 0X добавляется префикс к результатам, если преобразованное значение не равно нулю.
N/A
u

Преобразует целое число без знака в десятичное представление dddd.

  • Точность задаёт минимальное количество отображаемых цифр.
  • Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
N/A
f
F (C99)

Преобразует число с плавающей запятой в десятичную запись в стиле [-]ddd.ddd.

  • Точность задаёт точное количество цифр, отображаемых после десятичной точки.
  • Точность по умолчанию — 6.
  • В альтернативной реализации десятичная точка записывается, даже если за ней не следует цифр.
  • Для стилей преобразования бесконечности и NaN см. примечания.
N/A N/A
double
double (C99)
N/A N/A N/A N/A
long double
e
E

Преобразует число с плавающей запятой в десятичную экспоненциальную запись.

  • Для стиля преобразования e используется [-]d.ddd e±dd.
  • Для стиля преобразования E используется [-]d.ddd E±dd.
  • Экспонента содержит не менее двух цифр, больше цифр используется только при необходимости.
  • Если значение равно 0, экспонента также равна 0.
  • Точность задаёт точное количество цифр, отображаемых после десятичной точки.
  • Точность по умолчанию — 6.
  • В альтернативной реализации десятичная точка записывается, даже если за ней не следует цифр.
  • Для стилей преобразования бесконечности и NaN см. примечания.
N/A N/A N/A N/A N/A N/A
a
A

(C99)

Преобразует число с плавающей запятой в шестнадцатеричную экспоненциальную запись.

  • Для стиля преобразования a используется [-] 0xh.hhh p±d.
  • Для стиля преобразования A используется [-] 0Xh.hhh P±d.
  • Первая шестнадцатеричная цифра не равна 0, если аргумент является нормализованным значением с плавающей запятой.
  • Если значение равно 0, экспонента также равна 0.
  • Точность задаёт точное количество цифр, отображаемых после шестнадцатеричной точки.
  • Точность по умолчанию достаточна для точного представления значения.
  • В альтернативной реализации десятичная точка записывается, даже если за ней не следует цифр.
  • Для стилей преобразования бесконечности и NaN см. примечания.
N/A N/A N/A N/A N/A N/A
g
G

Преобразует число с плавающей запятой в десятичную или десятичную экспоненциальную запись в зависимости от значения и точности.

  • Для стиля преобразования g будет выполнено преобразование в стиле e или f.
  • Для стиля преобразования G будет выполнено преобразование в стиле E или f(до C99)F(начиная с C99).
  • Пусть P равно точности, если она ненулевая, 6, если точность не указана, или 1, если точность равна 0. Тогда, если преобразование в стиле E имело бы экспоненту X:
    • Если P > X ≥ −4, преобразование выполняется в стиле f или F(начиная с C99) с точностью P − 1 − X.
    • В противном случае преобразование выполняется в стиле e или E с точностью P − 1.
  • Если не запрошено альтернативное представление, конечные нули удаляются, а также удаляется десятичная точка, если не осталось дробной части.
  • Для стилей преобразования бесконечности и NaN см. примечания.
N/A N/A N/A N/A N/A N/A
n

Возвращает количество записанных символов на данный момент этим вызовом функции.

  • Результат записывается в значение, на которое указывает аргумент.
  • Спецификация не может содержать никаких флагов, ширины поля или точности.
  • Для модификатора z ожидаемый тип аргумента — S*, где S — версия со знаком size_t.
signed char*
short*
int*
long*
long long*
intmax_t*
※
 ptrdiff_t* 
N/A
p

Записывает определяемую реализацией последовательность символов, определяющую указатель.

N/A N/A
void*
N/A N/A N/A N/A N/A N/A
Примечания

Функции преобразования чисел с плавающей запятой преобразуют бесконечность в inf или infinity. Какая из них используется, определяется реализацией.

NaN преобразуется в nan или nan(char_sequence). Какая из них используется, определяется реализацией.

Преобразования F, E, G, A вместо этого выводят INF, INFINITY, NAN.

Спецификатор преобразования, используемый для печати char, unsigned char, signed char, short и unsigned short, ожидает продвинутые типы продвижения аргументов по умолчанию, но перед печатью его значение будет преобразовано в char, unsigned char, signed char, short и unsigned short. Безопасно передавать значения этих типов из-за продвижения, которое происходит при вызове вариативной функции.

Правильные спецификации преобразования для символьных типов фиксированной ширины (int8_t и т. д.) определены в заголовке <inttypes.h> (хотя PRIdMAX, PRIuMAX и т. д. являются синонимами %jd, %ju и т. д.).

Спецификатор преобразования, записывающий в память, %n является распространённой целью эксплуатации уязвимостей, когда строки формата зависят от пользовательского ввода, и не поддерживается семейством функций с проверкой границ printf_s (начиная с C11)(начиная с C11).

Существует точка следования после действия каждого спецификатора преобразования; это позволяет сохранять несколько результатов %n в одной и той же переменной или, как частный случай, печатать строку, изменённую более ранним %n в том же вызове.

Если спецификация преобразования недействительна, поведение не определено.

Возвращаемое значение

1-3) Количество записанных символов в случае успеха или отрицательное значение, если произошла ошибка.
4) Количество записанных символов в случае успеха или отрицательное значение, если произошла ошибка. Если результирующая строка усекается из-за ограничения buf_size, функция возвращает общее количество символов (не включая завершающий нулевой байт), которое было бы записано, если бы ограничение не было наложено.
5,6) количество символов, переданных в выходной поток, или отрицательное значение, если произошла ошибка вывода, ошибка нарушения ограничений времени выполнения или ошибка кодирования.
7) количество символов, записанных в buffer, не считая нулевого символа (который всегда записывается, если только buffer не является нулевым указателем, а bufsz не равно нулю и не больше RSIZE_MAX), или ноль при нарушениях ограничений времени выполнения и отрицательное значение при ошибках кодирования
8) количество символов, не включая завершающий нулевой символ (который всегда записывается, если только buffer не является нулевым указателем, а bufsz не равно нулю и не больше RSIZE_MAX), которые были бы записаны в buffer, если бы bufsz игнорировался, или отрицательное значение, если произошло нарушение ограничений времени выполнения или ошибка кодирования

Примечания

Все эти функции вызывают va_arg хотя бы один раз; значение arg неопределено после возврата. Эти функции не вызывают va_end, это должен сделать вызывающий.

vsnprintf_s, в отличие от vsprintf_s, усечёт результат, чтобы он поместился в массив, указанный buffer.

Реализация vsnprintf_s в Microsoft CRT не соответствует стандарту C. Версия Microsoft имеет дополнительный параметр size_t count на третьей позиции, который содержит максимальное количество символов для записи, не включая завершающий ноль. Этот параметр может отличаться от размера буфера, заданного параметром size_t bufsz.

Пример

#include <stdarg.h>
#include <stdio.h>
#include <time.h>

void debug_log(const char* fmt, ...)
{
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    char time_buf[100];
    size_t rc = strftime(time_buf, sizeof time_buf, "%D %T", gmtime(&ts.tv_sec));
    snprintf(time_buf + rc, sizeof time_buf - rc, ".%06ld UTC", ts.tv_nsec / 1000);

    va_list args1;
    va_start(args1, fmt);
    va_list args2;
    va_copy(args2, args1);
    char buf[1+vsnprintf(NULL, 0, fmt, args1)];
    va_end(args1);
    vsnprintf(buf, sizeof buf, fmt, args2);
    va_end(args2);

    printf("%s [debug]: %s\n", time_buf, buf);
}

int main(void)
{
    debug_log("Logging, %d, %d, %d", 1, 2, 3);
}

Возможный вывод:

02/20/15 21:58:09.072683 UTC [debug]: Logging, 1, 2, 3

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 7.21.6.8 Функция vfprintf (p: TBD)
  • 7.21.6.10 Функция vprintf (p: TBD)
  • 7.21.6.12 Функция vsnprintf (p: TBD)
  • 7.21.6.13 Функция vsprintf (p: TBD)
  • K.3.5.3.8 Функция vfprintf_s (p: TBD)
  • K.3.5.3.10 Функция vprintf_s (p: TBD)
  • K.3.5.3.12 Функция vsnprintf_s (p: TBD)
  • K.3.5.3.13 Функция vsprintf_s (p: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.21.6.8 Функция vfprintf (p: 238)
  • 7.21.6.10 Функция vprintf (p: 239)
  • 7.21.6.12 Функция vsnprintf (p: 239-240)
  • 7.21.6.13 Функция vsprintf (p: 240)
  • K.3.5.3.8 Функция vfprintf_s (p: 434)
  • K.3.5.3.10 Функция vprintf_s (p: 435)
  • K.3.5.3.12 Функция vsnprintf_s (p: 436-437)
  • K.3.5.3.13 Функция vsprintf_s (p: 437)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.21.6.8 Функция vfprintf (p: 326-327)
  • 7.21.6.10 Функция vprintf (p: 328)
  • 7.21.6.12 Функция vsnprintf (p: 329)
  • 7.21.6.13 Функция vsprintf (p: 329)
  • K.3.5.3.8 Функция vfprintf_s (p: 597)
  • K.3.5.3.10 Функция vprintf_s (p: 598-599)
  • K.3.5.3.12 Функция vsnprintf_s (p: 600)
  • K.3.5.3.13 Функция vsprintf_s (p: 601)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.19.6.8 Функция vfprintf (p: 292)
  • 7.19.6.10 Функция vprintf (p: 293)
  • 7.19.6.12 Функция vsnprintf (p: 294)
  • 7.19.6.13 Функция vsprintf (p: 295)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 4.9.6.7 Функция vfprintf
  • 4.9.6.8 Функция vprintf
  • 4.9.6.9 Функция vsprintf

См. также

выводит форматированный широкий символьный вывод в stdout, файловый поток
или буфер, используя список переменных аргументов
(функция)
выводит форматированный вывод в stdout, файловый поток или буфер
(функция)
читает форматированный ввод из stdin, файлового потока или буфера
с использованием списка переменных аргументов
(функция)
Документация C++ для vprintf, vfprintf, vsprintf, vsnprintf