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, преобразует их в строковые эквиваленты и записывает результаты в различные потоки.
stdout.stream.buffer.buffer. Максимально bufsz - 1 символов записываются. Результирующая строка символов завершается нулевым символом, если bufsz не равно нулю. Если bufsz равно нулю, ничего не записывается, и buffer может быть указателем на NULL, однако значение возврата (количество записанных байтов без учёта нулевого терминатора) всё равно вычисляется и возвращается.- спецификатор преобразования
%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 | Записывает один символ. Аргумент сначала преобразуется в | Н/Д | Н/Д |
int |
wint_t | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
s | Записывает строку символов Аргумент должен быть указателем на начальный элемент массива символов. Точность определяет максимальное количество байтов, которые будут записаны. Если точность не указана, записываются все байты до первого нулевого терминатора. Если используется спецификатор l, аргумент должен быть указателем на начальный элемент массива | Н/Д | Н/Д |
char* |
wchar_t* | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
di | Преобразует целое число со знаком в десятичное представление [-]dddd. Точность определяет минимальное количество цифр, которое должно отображаться. По умолчанию точность составляет |
signed char |
short |
int |
long |
long long |
целое со знаком size_t
| Н/Д | ||
o | Преобразует целое число без знака в восьмеричное представление oooo. Точность определяет минимальное количество цифр, которое должно отображаться. По умолчанию точность составляет |
unsigned char |
unsigned short |
unsigned int |
unsigned long |
unsigned long long |
беззнаковое представление ptrdiff_t
| Н/Д | ||
xX | Преобразует целое число без знака в шестнадцатеричное представление hhhh. Для преобразования | Н/Д | ||||||||
u | Преобразует целое число без знака в десятичное представление dddd. Точность определяет минимальное количество цифр, которое должно отображаться. По умолчанию точность составляет | Н/Д | ||||||||
fF | Преобразует число с плавающей точкой в десятичное представление в формате [-]ddd.ddd. Точность определяет точное количество цифр после десятичной точки. По умолчанию точность составляет | Н/Д | Н/Д |
double |
double(C99)
| Н/Д | Н/Д | Н/Д | Н/Д |
long double |
eE | Преобразует число с плавающей точкой в десятичное экспоненциальное представление. Для преобразования | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
aA (C99) | Преобразует число с плавающей точкой в шестнадцатеричное экспоненциальное представление. Для преобразования | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
gG | Преобразует число с плавающей точкой в десятичное или десятичное экспоненциальное представление в зависимости от значения и точности. Для преобразования
Если не запрошено альтернативное представление, хвостовые нули удаляются, а также десятичная точка удаляется, если дробная часть отсутствует. Для бесконечности и нечисловых значений см. примечания. | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
n | Возвращает количество записанных символов на данный момент вызовом функции. Результат записывается в значение, указанное аргументом. Спецификация может не содержать флаги, ширину поля или точность. |
signed char* |
short* |
int* |
long* |
long long* |
знаковый size_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 в рамках одного вызова.
Если спецификация преобразования некорректна, поведение не определено.
Значение возврата
buf_size ограничения, функция возвращает общее количество символов (не включая завершающий нулевой символ), которые были бы записаны, если бы ограничение не было применено.buffer, не считая нулевой символ (который всегда записывается, если buffer не является нулевым указателем и bufsz не равно нулю и не больше RSIZE_MAX), или ноль при нарушениях временных ограничений, и отрицательное значение при ошибках кодирования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
См. также
|
(C95)(C95)(C95)(C11)(C11)(C11)(C11) | выводит форматированный вывод широких символов в stdout, поток файлаили буфер, используя список аргументов переменной длины (функция) |
|
(C99)(C11)(C11)(C11)(C11) | выводит форматированный вывод в stdout, поток файла или буфер (функция) |
|
(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