Spec-Zone.ru › C

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

Определено в заголовочном файле <stdio.h>
(1)
int vprintf( const char *format, va_list vlist );
(до C99)
int vprintf( const char *restrict format, va_list vlist );
(с C99)
(2)
int vfprintf( FILE *stream, const char *format, va_list vlist );
(до C99)
int vfprintf( FILE *restrict stream, const char *restrict format, 
              va_list vlist );
(с C99)
(3)
int vsprintf( char *buffer, const char *format, va_list vlist );
(до 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 может быть указателем на NULL, однако значение возврата (количество записанных байтов без учёта нулевого терминатора) всё равно вычисляется и возвращается.
5-8) То же, что и (1-4), за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают текущую установленную функцию обработчика ошибок обработчика ограничений:
  • спецификатор преобразования %n присутствует в format
  • любой из аргументов, соответствующих %s, является указателем на NULL
  • format или buffer является указателем на NULL
  • 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

(C99)

h (ничего) l ll

(C99)

j

(C99)

z

(C99)

t

(C99)

L
% Записывает литерал %. Полная спецификация преобразования должна быть %%. Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
c Записывает один символ.

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

Н/Д Н/Д
int
wint_t
Н/Д Н/Д Н/Д Н/Д Н/Д
s Записывает строку символов

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

Н/Д Н/Д
char*
wchar_t*
Н/Д Н/Д Н/Д Н/Д Н/Д
d
i
Преобразует целое число со знаком в десятичное представление [-]dddd.

Точность определяет минимальное количество цифр, которое должно отображаться. По умолчанию точность составляет 1.

Если как преобразованное значение, так и точность равны ​0​ результат преобразования не содержит символов.

signed char
short
int
long
long long
intmax_t
целое со знаком size_t
ptrdiff_t
Н/Д
o Преобразует целое число без знака в восьмеричное представление oooo.

Точность определяет минимальное количество цифр, которое должно отображаться. По умолчанию точность составляет 1. Если как преобразованное значение, так и точность равны ​0​ результат преобразования не содержит символов. В альтернативной реализации точность увеличивается при необходимости, чтобы записать одну ведущую ноль. В этом случае, если и преобразованное значение, и точность равны ​0​, записывается одиночный ​0​.

unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
uintmax_t
size_t
беззнаковое представление ptrdiff_t
Н/Д
x
X
Преобразует целое число без знака в шестнадцатеричное представление hhhh.

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

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

Точность определяет минимальное количество цифр, которое должно отображаться. По умолчанию точность составляет 1. Если как преобразованное значение, так и точность равны ​0​ результат преобразования не содержит символов.

Н/Д
f
F
Преобразует число с плавающей точкой в десятичное представление в формате [-]ddd.ddd.

Точность определяет точное количество цифр после десятичной точки. По умолчанию точность составляет 6. В альтернативной реализации десятичная точка записывается, даже если за ней нет цифр. Для бесконечности и нечисловых значений см. примечания.

Н/Д Н/Д
double
double(C99)
Н/Д Н/Д Н/Д Н/Д
long double
e
E
Преобразует число с плавающей точкой в десятичное экспоненциальное представление.

Для преобразования e используется формат [-]d.ddde±dd.
Для преобразования E используется формат [-]d.dddE±dd.
Экспонента содержит не менее двух цифр, больше цифр используется только при необходимости. Если значение равно ​0​, экспонента также ​0​. Точность определяет точное количество цифр после десятичной точки. По умолчанию точность составляет 6. В альтернативной реализации десятичная точка записывается, даже если за ней нет цифр. Для бесконечности и нечисловых значений см. примечания.

Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
a
A

(C99)

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

Для преобразования a используется формат [-]0xh.hhhp±d.
Для преобразования A используется формат [-]0Xh.hhhP±d.
Первая шестнадцатеричная цифра не 0 если аргумент является нормализованным значением с плавающей точкой. Если значение равно ​0​, экспонента также ​0​. Точность определяет точное количество цифр после шестнадцатеричной точки. По умолчанию точность достаточна для точного представления значения. В альтернативной реализации десятичная точка записывается, даже если за ней нет цифр. Для бесконечности и нечисловых значений см. примечания.

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

Для преобразования g будет выполнено преобразование в стиле e или f.
Для преобразования G будет выполнено преобразование в стиле E или F.
Пусть P равно точности, если она отлична от нуля, 6 если точность не указана, или 1 если точность ​0​. Тогда, если преобразование в стиле E имело бы экспоненту X:

  • если P > X ≥ −4, преобразование выполняется в стиле f или F с точностью P − 1 − X.
  • в противном случае, преобразование выполняется в стиле e или E с точностью P − 1.

Если не запрошено альтернативное представление, хвостовые нули удаляются, а также десятичная точка удаляется, если дробная часть отсутствует. Для бесконечности и нечисловых значений см. примечания.

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

Результат записывается в значение, указанное аргументом. Спецификация может не содержать флаги, ширину поля или точность.



signed char*
short*
int*
long*
long long*
intmax_t*
знаковый size_t*
ptrdiff_t*
Н/Д
p Записывает определённую реализацией последовательность символов, определяющую указатель. Н/Д Н/Д void* Н/Д Н/Д Н/Д Н/Д Н/Д

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

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

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

Несмотря на то, что %c ожидает аргумент int, безопасно передавать char, из-за преобразования типов целых чисел, происходящего при вызове функций с переменным числом аргументов.

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

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

После действия каждого спецификатора преобразования есть точка последовательности; это позволяет сохранять несколько результатов %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.

Пример

#include <stdio.h>
#include <stdarg.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

Ссылки

  • Стандарт 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/w/c/io/vfprintf

Spec-Zone.ru

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