Spec-Zone.ru › C

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

Определён в заголовочном файле <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 состоит из обычных байтовых символов (за исключением %), которые без изменений копируются в выходной поток, и спецификаторов преобразования. Каждый спецификатор преобразования имеет следующий формат:

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

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

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

Записывает один символ.

  • Сначала аргумент преобразуется в unsignedchar.
  • Если используется модификатор l, сначала аргумент преобразуется в символьную строку, как если бы использовался %ls с аргументом wchar_t[2].
Н/Д Н/Д
int
wint_t
Н/Д Н/Д Н/Д Н/Д Н/Д
s

Записывает символьную строку.

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

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

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

(C23)

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

  • Точность задаёт минимальное число выводимых цифр. Точность по умолчанию равна 1.
  • Если и преобразуемое значение, и точность равны 0, результатом преобразования будет отсутствие символов.
  • В альтернативной форме перед результатом добавляется 0b или 0B, если преобразуемое значение ненулевое.
unsignedchar
unsignedshort
unsignedint
unsignedlong
unsignedlonglong
uintmax_t
size_t
версия без знака ptrdiff_t
Н/Д
o

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

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

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

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

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

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

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

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

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

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

(C99)

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

  • Для стиля преобразования a используется [-] 0xh.hhh p±d.
  • Для стиля преобразования A используется [-] 0Xh.hhh P±d.
  • Первая шестнадцатеричная цифра не 0, если аргумент является нормализованным числом с плавающей точкой.
  • Если значение равно 0, показатель степени также равен 0.
  • Точность задаёт точное число цифр после символа шестнадцатеричной точки.
  • Точность по умолчанию достаточна для точного представления значения.
  • В альтернативной форме символ десятичной точки записывается, даже если после него нет цифр.
  • О преобразовании бесконечности и нечисловых значений см. примечания.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
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.
  • Если не запрошено альтернативное представление, завершающие нули удаляются; символ десятичной точки также удаляется, если дробная часть отсутствует.
  • О преобразовании бесконечности и нечисловых значений см. примечания.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
n

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

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

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

Н/Д Н/Д
void*
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
Примечания

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

Нечисловое значение преобразуется в nan или nan(char_sequence). Используемый вариант определяется реализацией.

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

Спецификатор преобразования, используемый для вывода char, unsignedchar, signedchar, short и unsignedshort, ожидает типы, полученные в результате стандартных преобразований аргументов по умолчанию, но перед выводом значение преобразуется в char, unsignedchar, signedchar, short и unsignedshort. Передача значений этих типов безопасна благодаря повышению типа, которое выполняется при вызове функции с переменным числом аргументов.

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

Спецификатор преобразования %n, записывающий данные в память, часто становится целью атак, использующих строки формата, зависящие от пользовательского ввода, и не поддерживается семейством функций printf_s с проверкой границ(начиная с 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 (с. TBD)
    • 7.21.6.10 Функция vprintf (с. TBD)
    • 7.21.6.12 Функция vsnprintf (с. TBD)
    • 7.21.6.13 Функция vsprintf (с. TBD)
    • K.3.5.3.8 Функция vfprintf_s (с. TBD)
    • K.3.5.3.10 Функция vprintf_s (с. TBD)
    • K.3.5.3.12 Функция vsnprintf_s (с. TBD)
    • K.3.5.3.13 Функция vsprintf_s (с. TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
    • 7.21.6.8 Функция vfprintf (с. 238)
    • 7.21.6.10 Функция vprintf (с. 239)
    • 7.21.6.12 Функция vsnprintf (с. 239-240)
    • 7.21.6.13 Функция vsprintf (с. 240)
    • K.3.5.3.8 Функция vfprintf_s (с. 434)
    • K.3.5.3.10 Функция vprintf_s (с. 435)
    • K.3.5.3.12 Функция vsnprintf_s (с. 436-437)
    • K.3.5.3.13 Функция vsprintf_s (с. 437)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 7.21.6.8 Функция vfprintf (с. 326-327)
    • 7.21.6.10 Функция vprintf (с. 328)
    • 7.21.6.12 Функция vsnprintf (с. 329)
    • 7.21.6.13 Функция vsprintf (с. 329)
    • K.3.5.3.8 Функция vfprintf_s (с. 597)
    • K.3.5.3.10 Функция vprintf_s (с. 598-599)
    • K.3.5.3.12 Функция vsnprintf_s (с. 600)
    • K.3.5.3.13 Функция vsprintf_s (с. 601)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 7.19.6.8 Функция vfprintf (с. 292)
    • 7.19.6.10 Функция vprintf (с. 293)
    • 7.19.6.12 Функция vsnprintf (с. 294)
    • 7.19.6.13 Функция vsprintf (с. 295)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
    • 4.9.6.7 Функция vfprintf
    • 4.9.6.8 Функция vprintf
    • 4.9.6.9 Функция vsprintf

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/io/vfprintf

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API