Namespaces
Variants

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

From cppreference.net
< c ‎ | io
Определено в заголовке <stdio.h>
(1)
int printf ( const char * format, ... ) ;
(до C99)
int printf ( const char * restrict format, ... ) ;
(начиная с C99)
(2)
int fprintf ( FILE * stream, const char * format, ... ) ;
(до C99)
int fprintf ( FILE * restrict stream, const char * restrict format, ... ) ;
(начиная с C99)
(3)
int sprintf ( char * buffer, const char * format, ... ) ;
(до 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 , лишние аргументы вычисляются и игнорируются.

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

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

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

Спецификатор
преобразования
Объяснение Ожидаемый
тип аргумента
Модификатор длины→ hh h нет l ll j z t L
Доступно только с C99→ Да Да Да Да Да
% Выводит символ % . Полная спецификация преобразования должна быть %% . 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
wint_t
N/A N/A N/A N/A N/A
s

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

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

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

  • Точность определяет минимальное количество отображаемых цифр. Точность по умолчанию равна 1 .
  • Если и преобразованное значение, и точность равны 0 , преобразование не выводит символов.
  • Для модификатора z ожидаемый тип аргумента - знаковая версия 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
беззнаковая версия ptrdiff_t
N/A
x
X

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

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

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

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

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

  • Точность определяет точное количество цифр после десятичного разделителя.
  • Точность по умолчанию составляет 6 .
  • В альтернативной реализации десятичный разделитель записывается даже если за ним не следуют цифры.
  • Для стиля преобразования бесконечности и не-числа смотрите примечания .
N/A N/A
double
double (C99)
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

(C99)

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

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

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

  • Результат записывается в значение, на которое указывает аргумент.
  • Спецификация не должна содержать никаких флагов , ширины поля или точности .
  • Для модификатора z ожидаемый тип аргумента - S * , где S - знаковая версия 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 или 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); // <- сломанный: неопределённое поведение

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]; // обратите внимание на +1 для завершающего нулевого байта
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