Spec-Zone.ru › C

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

Определено в заголовочном файле <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

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

  • Аргумент сначала преобразуется в unsignedchar.
  • Если используется модификатор 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.
signedchar
short
int
long
longlong
intmax_t
※
ptrdiff_t
Н/Д
b
B (необязательно)

(C23)

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

  • Точность задаёт минимальное количество выводимых цифр. Точность по умолчанию — 1.
  • Если и преобразованное значение, и точность равны 0, преобразование не даёт символов.
  • При альтернативной форме перед результатом, если преобразованное значение не равно нулю, ставится 0b или 0B.
unsignedchar
unsignedshort
unsignedint
unsignedlong
unsignedlonglong
uintmax_t
size_t
беззнаковый вариант 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)
Н/Д Н/Д Н/Д Н/Д
longdouble
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.
signedchar*
short*
int*
long*
longlong*
intmax_t*
※
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. Передавать значения этих типов безопасно благодаря повышению, которое происходит при вызове функции с переменным числом аргументов.

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

См. также

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

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/c/io/fprintf

Spec-Zone.ru

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