Namespaces
Variants

std:: printf, std:: fprintf, std:: sprintf, std:: snprintf

From cppreference.net
< cpp ‎ | io ‎ | c
Определено в заголовочном файле <cstdio>
int printf ( const char * format, ... ) ;
(1)
int fprintf ( std:: FILE * stream, const char * format, ... ) ;
(2)
int sprintf ( char * buffer, const char * format, ... ) ;
(3)
int snprintf ( char * buffer, std:: size_t buf_size, const char * format, ... ) ;
(4) (начиная с C++11)

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

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

Если вызов sprintf или snprintf приводит к копированию между перекрывающимися объектами, поведение не определено (например, sprintf ( buf, "%s text" , buf ) ; ).

Содержание

Параметры

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

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

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

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

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

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

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

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

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

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

  • Точность определяет минимальное количество отображаемых цифр. Точность по умолчанию равна 1 .
  • Если и преобразованное значение, и точность равны 0 , преобразование не выводит символов.
  • Для модификатора z ожидаемый тип аргумента - знаковая версия std::size_t .
signed char
short
int
long
long long
N/A
o

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

  • Точность определяет минимальное количество отображаемых цифр. Точность по умолчанию равна 1 .
  • Если и преобразованное значение, и точность равны 0 , преобразование не выводит символов.
  • В альтернативной реализации точность увеличивается при необходимости для записи одного ведущего нуля. В этом случае, если и преобразованное значение, и точность равны 0 , записывается один 0 .
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
беззнаковая версия std::ptrdiff_t
N/A
x
X

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

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

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

  • Точность определяет минимальное количество отображаемых цифр.
  • Точность по умолчанию равна 1 .
  • Если и преобразованное значение, и точность равны 0 , преобразование не выводит символов.
N/A
f
F (C++11)

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

  • Точность определяет точное количество цифр, отображаемых после десятичного разделителя.
  • Точность по умолчанию составляет 6 .
  • В альтернативной реализации десятичный разделитель записывается даже если за ним не следуют цифры.
  • Для преобразования бесконечности и не-числа смотрите примечания .
N/A N/A
double
double (C++11)
N/A N/A N/A N/A
long double
e
E

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

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

(C++11)

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

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

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

  • Результат записывается в значение, на которое указывает аргумент.
  • Спецификатор не может содержать никаких флагов , ширины поля или точности .
  • Для модификатора z ожидаемый тип аргумента - S * , где S - это знаковая версия std:: size_t .
signed char *
short *
int *
long *
long long *
N/A
p

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

N/A N/A
void *
N/A N/A N/A N/A N/A N/A
Примечания

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

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

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

Спецификатор преобразования, используемый для вывода char , unsigned char , signed char , short и unsigned short , ожидает продвинутые типы стандартных продвижений аргументов , но перед выводом его значение будет преобразовано в char , unsigned char , signed char , short и unsigned short . Безопасно передавать значения этих типов из-за продвижения, которое происходит при вызове вариативной функции.

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

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

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

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

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

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

Примечания

POSIX определяет , что errno устанавливается при ошибке. Также специфицируются дополнительные спецификаторы преобразования, наиболее примечательно — поддержка изменения порядка аргументов ( n$ сразу после % указывает на n аргумент).

Вызов std::snprintf с нулевым buf_size и нулевым указателем для buffer полезен (когда допустимы накладные расходы двойного вызова) для определения необходимого размера буфера для хранения вывода:

auto fmt = "sqrt(2) = %f";
int sz = std::snprintf(nullptr, 0, fmt, std::sqrt(2));
std::vector<char> buf(sz + 1); // примечание: +1 для нуль-терминатора
std::sprintf(buf.data(), fmt, std::sqrt(2)); // гарантированно поместится

Пример

#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <limits>
int main()
{
    const char* s = "Hello";
    std::printf("Strings:\n"); // same as std::puts("Strings:");
    std::printf("\t[%10s]\n", s);
    std::printf("\t[%-10s]\n", s);
    std::printf("\t[%*s]\n", 10, s);
    std::printf("\t[%-10.*s]\n", 4, s);
    std::printf("\t[%-*.*s]\n", 10, 4, s);
    std::printf("Characters:\t%c %%\n", 'A');
    std::printf("Integers:\n");
    std::printf("\tDecimal:    \t%i %d %.6i %i %.0i %+i %i\n",
                                  1, 2,   3, 0,   0,  4,-4);
    std::printf("\tHexadecimal:\t%x %x %X %#x\n",
                                  5,10,10,  6);
    std::printf("\tOctal:      \t%o %#o %#o\n",
                                 10, 10,  4);
    std::printf("Floating point:\n");
    std::printf("\tRounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
    std::printf("\tPadding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
    std::printf("\tScientific:\t%E %e\n", 1.5, 1.5);
    std::printf("\tHexadecimal:\t%a %A\n", 1.5, 1.5);
    std::printf("\tSpecial values:\t0/0=%g 1/0=%g\n", 0.0/0.0, 1.0/0.0);
    std::printf("Variable width control:\n");
    std::printf("\tright-justified variable width: '%*c'\n", 5, 'x');
    int r = std::printf("\tleft-justified variable width : '%*c'\n", -5, 'x');
    std::printf("(the last printf printed %d characters)\n", r);
    std::printf("Fixed-width types:\n");
    std::uint32_t val = std::numeric_limits<std::uint32_t>::max();
    std::printf("\tLargest 32-bit value is %" PRIu32 " or %#" PRIx32 "\n",
                                                 val,            val);
}

Возможный вывод:

Strings:
	[     Hello]
	[Hello     ]
	[     Hello]
	[Hell      ]
	[Hell      ]
Characters:	A %
Integers:
	Decimal:    	1 2 000003 0  +4 -4
	Hexadecimal:	5 a A 0x6
	Octal:      	12 012 04
Floating point:
	Rounding:	1.500000 2 1.30000000000000004440892098500626
	Padding:	01.50 1.50  1.50
	Scientific:	1.500000E+00 1.500000e+00
	Hexadecimal:	0x1.8p+0 0X1.8P+0
	Special values:	0/0=-nan 1/0=inf
Variable width control:
	right-justified variable width: '    x'
	left-justified variable width : 'x    '
(the last printf printed 41 characters)
Fixed-width types:
	Largest 32-bit value is 4294967295 or 0xffffffff

Смотрите также

выводит форматированные широкие символы в stdout , файловый поток или буфер
(функция)
выводит форматированные данные в stdout , файловый поток или буфер
используя список переменных аргументов
(функция)
записывает строку символов в файловый поток
(функция)
считывает форматированные данные из stdin , файлового потока или буфера
(функция)
(C++17)
преобразует целочисленное или вещественное значение в последовательность символов
(функция)
(C++23)
выводит в stdout или файловый поток, используя форматированное представление аргументов
(шаблон функции)
(C++23)
аналогично std::print , но каждый вывод завершается дополнительным переводом строки
(шаблон функции)
Документация C для printf , fprintf , sprintf , snprintf