std::printf, std::fprintf, std::sprintf, std::snprintf
Defined in header <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) | (since C++11) |
Загружает данные из указанных мест, преобразует их в строковые эквиваленты и записывает результаты в различные потоки.
stdout.stream.buffer.buffer. Максимальное количество buf_size - 1 символов. Результирующая строка символов будет завершена нулевым символом, если buf_size не равно нулю. Если buf_size равно нулю, ничего не записывается, и buffer может быть указателем на null, однако значение возврата (количество байтов, которые были бы записаны, не включая нулевой терминатор) все равно рассчитывается и возвращается.Если вызов sprintf или snprintf приводит к копированию между перекрывающимися объектами, поведение является неопределённым (например, sprintf(buf, "%s text", buf);).
Параметры
| stream | - | поток вывода файла для записи |
| buffer | - | указатель на строку символов для записи |
| buf_size | - | может быть записано до buf_size - 1 символов, плюс нулевой терминатор |
| format | - | указатель на завершающуюся нулём многобайтовую строку, определяющую способ интерпретации данных |
| ... | - | аргументы, определяющие данные для печати. Если любой аргумент после неявного преобразования не является типом, ожидаемым соответствующим спецификатором преобразования, или если количество аргументов меньше, чем требуется format, поведение является неопределённым. Если количество аргументов больше, чем требуется format, дополнительные аргументы оцениваются и игнорируются |
Строка format состоит из обычных байтовых символов (за исключением %), которые копируются без изменений в выходной поток, и спецификаторов преобразования. Каждая спецификация преобразования имеет следующий формат:
- вводящий
%символ. - (необязательно) один или несколько флагов, которые изменяют поведение преобразования:
-
-: результат преобразования выравнивается по левому краю в поле (по умолчанию выравнивание по правому краю). -
+: знак знакового преобразования всегда предшествует результату преобразования (по умолчанию результат предшествует минусом только в случае отрицательного значения). - пробел: если результат знакового преобразования не начинается с символа знака или пуст, пробел предшествует результату. Он игнорируется, если присутствует флаг
+. -
#: выполняется альтернативная форма преобразования. Точное влияние указано в таблице ниже, в противном случае поведение является неопределённым. -
0: для целых и с плавающей точкой чисел, ведущие нули используются для дополнения поля вместо символов пробел. Для целых чисел это игнорируется, если точность явно указана. Для других преобразований использование этого флага приводит к неопределённому поведению. Он игнорируется, если присутствует флаг-. - (необязательно) целое значение или
*которое задаёт минимальную ширину поля. Результат дополняется символами пробела (по умолчанию), если необходимо, слева при выравнивании по правому краю или справа при выравнивании по левому краю. В случае использования*, ширина определяется дополнительным аргументом типаint, который предшествует аргументу для преобразования и аргументу, задающему точность, если таковой имеется. Если значение аргумента отрицательное, это приводит к заданию флага-и положительной ширине поля (Примечание: Это минимальная ширина: значение никогда не усекается.). - (необязательно)
., за которым следует целое число или*, или ни то ни другое, что задаёт точность преобразования. В случае использования*, точность задаётся дополнительным аргументом типаint, который предшествует аргументу для преобразования, но после аргумента, задающего минимальную ширину поля, если таковой имеется. Если значение этого аргумента отрицательное, оно игнорируется. Если ни число, ни*не используются, точность принимается равной нулю. Точное влияние точности указано в таблице ниже. - (необязательно) модификатор длины, который задаёт размер аргумента (в сочетании со спецификатором формата преобразования, он задаёт тип соответствующего аргумента).
- спецификатор формата преобразования.
Доступны следующие спецификаторы формата:
| Преобразование спецификатор | Описание | Ожидаемый тип аргумента |
||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
Модификатор длины → |
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* | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
di | Преобразует целое число со знаком в десятичную запись [-]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
| Н/Д |
xX | Преобразует целое число без знака в шестнадцатеричную запись hhhh. Для x преобразования используются символы abcdef. Для X преобразования используются символы ABCDEF. Точность задаёт минимальное количество цифр. По умолчанию точность равна 1. Если преобразованное значение и точность равны 0, преобразование не даёт никаких результатов. В альтернативной реализации 0x или 0X добавляется в результат, если преобразованное значение не равно нулю. | Н/Д | ||||||||
u | Преобразует целое число без знака в десятичную запись dddd. Точность задаёт минимальное количество цифр. По умолчанию точность равна 1. Если преобразованное значение и точность равны 0, преобразование не даёт никаких результатов. | Н/Д | ||||||||
fF | Преобразует число с плавающей точкой в десятичную запись в стиле [-]ddd.ddd. Точность задаёт точное количество цифр после десятичной точки. По умолчанию точность равна 6. В альтернативной реализации десятичная точка выводится даже если за ней нет цифр. Для бесконечности и не-числовых значений см. примечания. | Н/Д | Н/Д |
double |
double(C++11)
| Н/Д | Н/Д | Н/Д | Н/Д |
long double |
eE | Преобразует число с плавающей точкой в экспоненциальную десятичную запись. Для e стиля преобразования используется [-]d.ddde±dd.Для E стиля преобразования используется [-]d.dddE±dd.Экспонента содержит по крайней мере две цифры, дополнительные цифры используются только при необходимости. Если значение равно 0, экспонента также равна 0. Точность задаёт точное количество цифр после десятичной точки. По умолчанию точность равна 6. В альтернативной реализации десятичная точка выводится даже если за ней нет цифр. Для бесконечности и не-числовых значений см. примечания. | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
aA (C++11) | Преобразует число с плавающей точкой в шестнадцатеричную экспоненциальную запись. Для a стиля преобразования используется [-]0xh.hhhp±d.Для A стиля преобразования используется [-]0Xh.hhhP±d.Первая шестнадцатеричная цифра не 0 если аргумент является нормализованным значением с плавающей точкой. Если значение равно 0, экспонента также равна 0. Точность задаёт точное количество цифр после шестнадцатеричной точки. По умолчанию точность достаточна для точного представления значения. В альтернативной реализации десятичная точка выводится даже если за ней нет цифр. Для бесконечности и не-числовых значений см. примечания. | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
gG | Преобразует число с плавающей точкой в десятичную или экспоненциальную десятичную запись в зависимости от значения и точности. Для 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 в том же вызове.
Если спецификация преобразования неверна, поведение является неопределённым.
Возвращаемое значение
buf_size. Примечания
POSIX определяет, что errno устанавливается при ошибке. Он также определяет дополнительные спецификации преобразования, в частности, поддержку переупорядочивания аргументов (n$ непосредственно после % указывает на n-й аргумент).
Вызов std::snprintf с нулевым buf_size и указателем null для buffer полезен (когда допустимы накладные расходы двойного вызова) для определения необходимого размера буфера для хранения вывода:
auto fmt = "sqrt(2) = %f"; int sz = std::snprintf(nullptr, 0, fmt, std::sqrt(2)); std::vector<char> buf(sz + 1); // note +1 for null terminator std::sprintf(buf.data(), fmt, std::sqrt(2)); // certain to fit
Пример
#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, поток файла или буфер (функция) |
|
|
(C++11) | выводит отформатированный вывод в stdout, поток файла или буфер с использованием списка аргументов переменной длины (функция) |
| записывает строку символов в поток файла (функция) |
|
считывает отформатированный ввод из stdin, потока файла или буфера (функция) |
|
|
(C++17) | преобразует целое или число с плавающей точкой в последовательность символов (функция) |
|
(C++23) | выводит в stdout или поток файла, используя отформатированное представление аргументов (шаблон функции) |
|
(C++23) | то же, что и std::print , но каждый вывод завершается дополнительной новой строкой (шаблон функции) |
C документация для printf, fprintf, sprintf, snprintf |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/io/c/fprintf