Spec-Zone.ru › C++

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

Определено в заголовочном файле <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, лишние аргументы вычисляются и игнорируются

Строка 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). Используемый вариант определяется реализацией.

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

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

Правильные спецификаторы преобразования для целочисленных типов фиксированной ширины (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); // 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

См. также

wprintffwprintfswprintf
выводит форматированный широкосимвольный текст в stdout, файловый поток или буфер
(функция)
vprintfvfprintfvsprintfvsnprintf
(C++11)
выводит форматированный текст в stdout, файловый поток или буфер
с использованием списка аргументов переменной длины
(функция)
fputs
записывает символьную строку в файловый поток
(функция)
scanffscanfsscanf
считывает форматированный ввод из stdin, файлового потока или буфера
(функция)
to_chars
(C++17)
преобразует целое число или значение с плавающей точкой в последовательность символов
(функция)
print
(C++23)
выводит в stdout или файловый поток аргументы в форматированном представлении
(шаблон функции)
println
(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/cpp/io/c/printf

Spec-Zone.ru

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