Spec-Zone.ru › C++

std::vprintf, std::vfprintf, std::vsprintf, std::vsnprintf

Определено в заголовочном файле <cstdio>
int vprintf( const char* format, std::va_list vlist );
(1)
int vfprintf( std::FILE* stream, const char* format, std::va_list vlist );
(2)
int vsprintf( char* buffer, const char* format, std::va_list vlist );
(3)
int vsnprintf( char* buffer, std::size_t buf_size, const char* format, std::va_list vlist );
(4) (с C++11)

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

1) Записывает результаты в stdout.
2) Записывает результаты в поток файла stream.
3) Записывает результаты в строку символов buffer.
4) Записывает результаты в строку символов buffer. Максимально buf_size - 1 символов записывается. Результирующая строка символов завершается нулевым символом, если buf_size не равно нулю. Если buf_size равно нулю, ничего не записывается, и buffer может быть нулевым указателем, однако возвращаемое значение (количество байтов, которые были бы записаны, не включая нулевой терминатор) всё равно вычисляется и возвращается.

Параметры

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

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

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

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

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

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

Преобразование
спецификатор
Объяснение Ожидаемый
тип аргумента
Модификатор
длины
→
hh

(C++11)

h (нет) l ll

(C++11)

j

(C++11)

z

(C++11)

t

(C++11)

L
% Выводит литерал %. Полная спецификация преобразования должна быть %%. Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
c Выводит один символ. Аргумент сначала преобразуется в unsigned char. Если используется модификатор l, аргумент сначала преобразуется в строку символов, как если бы использовался %ls с wchar_t[2] аргументом. Н/Д Н/Д
int
wint_t
Н/Д Н/Д Н/Д Н/Д Н/Д
s Выводит строку символов. Аргумент должен быть указателем на начальный элемент массива символов. Точность задаёт максимальное количество байтов для вывода. Если точность не указана, выводятся все байты до первого нулевого терминатора. Если используется спецификатор l, аргумент должен быть указателем на начальный элемент массива wchar_t, который преобразуется в массив char, как если бы был вызван 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(C++11)
Н/Д Н/Д Н/Д Н/Д
long double
e
E
Преобразует число с плавающей точкой в десятичное экспоненциальное представление. Для e стиля преобразования используется [-]d.ddde±dd.
Для E стиля преобразования используется [-]d.dddE±dd.
Экспонента содержит как минимум две цифры, больше цифр используются только если необходимо. Если значение равно ​0​, экспонента также равна ​0​. Точность задаёт количество цифр после десятичной точки. По умолчанию точность равна 6. В альтернативной реализации десятичная точка выводится даже если после неё нет цифр. Для бесконечности и нечисловых значений см. примечания.
Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
a
A

(C++11)

Преобразует число с плавающей точкой в шестнадцатеричное экспоненциальное представление. Для 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, Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
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, и т.д.) определены в заголовке <cinttypes> (хотя PRIdMAX, PRIuMAX, и т.д. является синонимом %jd, %ju, и т.д.).

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

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

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

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

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

Примечания

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

Пример

#include <cstdarg>
#include <cstdio>
#include <ctime>
#include <vector>
 
void debug_log(const char *fmt, ...)
{
    std::time_t t = std::time(nullptr);
    char time_buf[100];
    std::strftime(time_buf, sizeof time_buf, "%D %T", std::gmtime(&t));
    std::va_list args1;
    va_start(args1, fmt);
    std::va_list args2;
    va_copy(args2, args1);
    std::vector<char> buf(1 + std::vsnprintf(nullptr, 0, fmt, args1));
    va_end(args1);
    std::vsnprintf(buf.data(), buf.size(), fmt, args2);
    va_end(args2);
    std::printf("%s [debug]: %s\n", time_buf, buf.data());
}
 
int main()
{
    debug_log("Logging, %d, %d, %d", 1, 2, 3);
}

Вывод:

04/13/15 15:09:18 [debug]: Logging, 1, 2, 3

См. также

printffprintfsprintfsnprintf
(C++11)
печатает форматированный вывод в stdout, поток файла или буфер
(функция)
vscanfvfscanfvsscanf
(C++11)(C++11)(C++11)
считывает форматированный ввод из stdin, потока файла или буфера
используя список переменных аргументов
(функция)
vprint_unicode
(C++23)
печатает в поддерживающий Unicode stdout или поток файла, используя тип-стираемый аргумент
(функция)
vprint_nonunicode
(C++23)
печатает в stdout или поток файла, используя тип-стираемый аргумент
(функция)
Документация C для vprintf, vfprintf, vsprintf, vsnprintf

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

Spec-Zone.ru

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