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, который передаётся перед преобразуемым аргументом, но после аргумента, задающего минимальную ширину поля, если он указан. Если значение этого аргумента отрицательно, оно игнорируется. Если не указаны ни число, ни *, точность принимается равной нулю. Точное действие точности описано в таблице ниже.
    • (необязательно) модификатор длины, задающий размер аргумента (в сочетании со спецификатором формата преобразования он задаёт тип соответствующего аргумента).
    • спецификатор формата преобразования.

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

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

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

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

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

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

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

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

(C++26)

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

  • Точность задаёт минимальное количество выводимых цифр. Точность по умолчанию — 1.
  • Если и преобразуемое значение, и точность равны 0, преобразование не даёт символов.
  • При альтернативной форме перед результатом, если преобразуемое значение ненулевое, добавляется 0b или 0B.
unsignedchar
unsignedshort
unsignedint
unsignedlong
unsignedlonglong
std::uintmax_t
std::size_t
беззнаковый вариант std::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 (C++11)

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

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

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

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

(C++11)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

После выполнения каждого спецификатора преобразования происходит точка последовательности; это позволяет сохранять результаты нескольких %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_unicodevprint_unicode_buffered
(C++23)
выводит данные в поддерживающий Unicode stdout или файловый поток, используя стираемое по типу представление аргументов
(функция)
vprint_nonunicodevprint_nonunicode_buffered
(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/cpp/io/c/vfprintf

Spec-Zone.ru

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