Namespaces
Variants

printf, fprintf, sprintf, snprintf, printf_s, fprintf_s, sprintf_s, snprintf_s

От ru.cppreference.net
< c | io
 
 
Файловый ввод/вывод
Типы и объекты
        
Функции
Доступ к файлам
(C95)
Неформатированный ввод/вывод
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

Форматированный ввод
Прямой ввод/вывод
Форматированный вывод
Позиционирование в файле
Обработка ошибок
Операции с файлами
 
Определено в заголовке <stdio.h>
int printf( const char* format, ... );
(1) (до C99)
int printf( const char* restrict format, ... );
(начиная с C99)
int fprintf( FILE* stream, const char* format, ... );
(2) (до C99)
int fprintf( FILE* restrict stream, const char* restrict format, ... );
(начиная с C99)
int sprintf( char* buffer, const char* format, ... );
(3) (до C99)
int sprintf( char* restrict buffer, const char* restrict format, ... );
(начиная с C99)
int snprintf( char* restrict buffer, size_t bufsz,
              const char* restrict format, ... );
(4) (начиная с C99)
int printf_s( const char* restrict format, ... );
(5) (начиная с C11)
int fprintf_s( FILE* restrict stream, const char* restrict format, ... );
(6) (начиная с C11)
int sprintf_s( char* restrict buffer, rsize_t bufsz,
               const char* restrict format, ... );
(7) (начиная с C11)
int snprintf_s( char* restrict buffer, rsize_t bufsz,
                const char* restrict format, ... );
(8) (начиная с C11)

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

1) Записывает результаты в выходной поток stdout.
2) Записывает результаты в выходной поток stream.
3) Записывает результаты в строку символов buffer. Поведение не определено, если строка, которая должна быть записана (плюс завершающий нулевой символ), превышает размер массива, на который указывает buffer.
4) Записывает результаты в строку символов buffer. Записывается не более bufsz - 1 символов. Результирующая строка символов будет завершена нулевым символом, если только bufsz не равно нулю. Если bufsz равно нулю, ничего не записывается, и buffer может быть нулевым указателем, однако возвращаемое значение (количество байтов, которое было бы записано без учёта завершающего нуля) всё равно вычисляется и возвращается.
5-8) То же, что и (1-4), за исключением того, что следующие ошибки обнаруживаются во время выполнения и вызывают установленную в данный момент функцию обработчика ограничений:
  • спецификатор преобразования %n присутствует в format
  • любой из аргументов, соответствующих %s является нулевым указателем
  • stream или format или buffer является нулевым указателем
  • bufsz равно нулю или больше RSIZE_MAX
  • возникают ошибки кодирования в любом из строковых и символьных спецификаторов преобразования
  • (для sprintf_s только), строка, которая должна быть сохранена в buffer (включая завершающий ноль), превысит bufsz.
Как и все функции с контролем границ, printf_s, fprintf_s, sprintf_s и snprintf_s гарантированно доступны только в том случае, если __STDC_LIB_EXT1__ определён реализацией и если пользователь определяет __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 до включения <stdio.h>.

Параметры

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

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

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

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

Преобразование
Спецификатор
Объяснение Ожидаемый
Тип аргумента
Модификатор длины→ hh h нет l ll j z t L
Доступно только начиная с C99→ Да Да Да Да Да
% Записывает литерал %. Полная спецификация преобразования должна быть %%. Н/П Н/П Н/П Н/П Н/П Н/П Н/П Н/П Н/П
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, преобразование не даёт символов.
  • Для модификатора z ожидаемый тип аргумента — знаковая версия size_t.
signed char
short
int
long
long long
intmax_t
※
ptrdiff_t
Н/П
b
B (необязательно)

(C23)

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

  • Точность задаёт минимальное количество отображаемых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
  • В альтернативной реализации 0b или 0B добавляется к результатам, если преобразованное значение отлично от нуля.
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
uintmax_t
size_t
unsigned версия 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 (C99)

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

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

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

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

(C99)

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

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

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

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

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

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

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

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

Функции преобразования с плавающей запятой преобразуют бесконечность в 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. Передавать значения этих типов безопасно из-за продвижения, которое происходит при вызове функции с переменным числом аргументов.

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

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

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

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

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

1,2) количество символов, переданных в выходной поток, или отрицательное значение, если произошла ошибка вывода или ошибка кодирования (для строковых и символьных спецификаторов преобразования).
3) количество символов, записанных в buffer (не считая завершающего нулевого символа), или отрицательное значение, если произошла ошибка кодирования (для строковых и символьных спецификаторов преобразования).
4) количество символов (не включая завершающий нулевой символ), которые были бы записаны в buffer, если бы bufsz был проигнорирован, или отрицательное значение, если произошла ошибка кодирования (для строковых и символьных спецификаторов преобразования).
5,6) количество символов, переданных в выходной поток, или отрицательное значение, если произошла ошибка вывода, ошибка нарушения ограничений времени выполнения или ошибка кодирования.
7) количество символов, записанных в buffer, не считая нулевого символа (который всегда записывается, если только buffer не является нулевым указателем, а bufsz не равно нулю и не больше RSIZE_MAX), или ноль при нарушениях ограничений времени выполнения, и отрицательное значение при ошибках кодирования.
8) количество символов, не включая завершающий нулевой символ (который всегда записывается, если только buffer не является нулевым указателем, а bufsz не равно нулю и не больше RSIZE_MAX), которые были бы записаны в buffer, если бы bufsz был проигнорирован, или отрицательное значение, если произошло нарушение ограничений времени выполнения или ошибка кодирования.

Примечания

Стандарт C и POSIX определяют, что поведение sprintf и его вариантов не определено, когда аргумент перекрывается с целевым буфером. Пример:

sprintf(dst, "%s and %s", dst, t); // <- broken: undefined behavior

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

Вызов snprintf с нулевым bufsz и нулевым указателем для buffer полезен для определения необходимого размера буфера для размещения вывода:

const char fmt[] = "sqrt(2) = %f";
int sz = snprintf(NULL, 0, fmt, sqrt(2));
char buf[sz + 1]; // note +1 for terminating null byte
snprintf(buf, sizeof buf, fmt, sqrt(2));

snprintf_s, как и snprintf, но в отличие от sprintf_s, усекает вывод, чтобы он поместился в bufsz - 1.

Пример

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

int main(void)
{
    const char* s = "Hello";
    printf("Strings:\n"); // same as puts("Strings");
    printf(" padding:\n");
    printf("\t[%10s]\n", s);
    printf("\t[%-10s]\n", s);
    printf("\t[%*s]\n", 10, s);
    printf(" truncating:\n");
    printf("\t%.4s\n", s);
    printf("\t%.*s\n", 3, s);

    printf("Characters:\t%c %%\n", 'A');

    printf("Integers:\n");
    printf("\tDecimal:\t%i %d %.6i %i %.0i %+i %i\n",
                         1, 2,   3, 0,   0,  4,-4);
    printf("\tHexadecimal:\t%x %x %X %#x\n", 5, 10, 10, 6);
    printf("\tOctal:\t\t%o %#o %#o\n", 10, 10, 4);

    printf("Floating-point:\n");
    printf("\tRounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
    printf("\tPadding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
    printf("\tScientific:\t%E %e\n", 1.5, 1.5);
    printf("\tHexadecimal:\t%a %A\n", 1.5, 1.5);
    printf("\tSpecial values:\t0/0=%g 1/0=%g\n", 0.0 / 0.0, 1.0 / 0.0);

    printf("Fixed-width types:\n");
    printf("\tLargest 32-bit value is %" PRIu32 " or %#" PRIx32 "\n",
                                     UINT32_MAX,     UINT32_MAX );
}

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

Strings:
 padding:
        [     Hello]
        [Hello     ]
        [     Hello]
 truncating:
        Hell
        Hel
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
Fixed-width types:
        Largest 32-bit value is 4294967295 or 0xffffffff

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
  • 7.21.6.1 Функция fprintf (стр.: TBD)
  • 7.21.6.3 Функция printf (стр.: TBD)
  • 7.21.6.5 Функция snprintf (стр.: TBD)
  • 7.21.6.6 Функция sprintf (стр.: TBD)
  • K.3.5.3.1 Функция fprintf_s (стр.: TBD)
  • K.3.5.3.3 Функция printf_s (стр.: TBD)
  • K.3.5.3.5 Функция snprintf_s (стр.: TBD)
  • K.3.5.3.6 Функция sprintf_s (стр.: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
  • 7.21.6.1 Функция fprintf (стр.: 225-230)
  • 7.21.6.3 Функция printf (стр.: 236)
  • 7.21.6.5 Функция snprintf (стр.: 237)
  • 7.21.6.6 Функция sprintf (стр.: 237)
  • K.3.5.3.1 Функция fprintf_s (стр.: 430)
  • K.3.5.3.3 Функция printf_s (стр.: 432)
  • K.3.5.3.5 Функция snprintf_s (стр.: 432-433)
  • K.3.5.3.6 Функция sprintf_s (стр.: 433)
  • Стандарт C11 (ISO/IEC 9899:2011):
  • 7.21.6.1 Функция fprintf (стр.: 309-316)
  • 7.21.6.3 Функция printf (стр.: 324)
  • 7.21.6.5 Функция snprintf (стр.: 325)
  • 7.21.6.6 Функция sprintf (стр.: 325-326)
  • K.3.5.3.1 Функция fprintf_s (стр.: 591)
  • K.3.5.3.3 Функция printf_s (стр.: 593-594)
  • K.3.5.3.5 Функция snprintf_s (стр.: 594-595)
  • K.3.5.3.6 Функция sprintf_s (стр.: 595-596)
  • Стандарт C99 (ISO/IEC 9899:1999):
  • 7.19.6.1 Функция fprintf (стр.: 274-282)
  • 7.19.6.3 Функция printf (стр.: 290)
  • 7.19.6.5 Функция snprintf (стр.: 290-291)
  • 7.19.6.6 Функция sprintf (стр.: 291)
  • Стандарт C89/C90 (ISO/IEC 9899:1990):
  • 4.9.6.1 Функция fprintf
  • 4.9.6.3 Функция printf
  • 4.9.6.5 Функция sprintf

См. также

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