Spec-Zone.ru › C

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

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


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

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

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

Спецификатор
преобразования
Описание Ожидаемый
тип аргумента
Модификатор
длины
→
hh

(C99)

h (не указано) l ll

(C99)

j

(C99)

z

(C99)

t

(C99)

L
% Выводит литерал %. Полная спецификация преобразования должна быть %%. Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
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​, результат преобразования пуст.

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
Н/Д
x
X
Преобразует целое без знака в шестнадцатеричное представление hhhh.

Для x преобразования используются символы abcdef.
Для X преобразования используются символы ABCDEF.
Точность задаёт минимальное количество цифр. Значение по умолчанию — 1. Если преобразованное значение и точность равны ​0​, результат преобразования пуст. В альтернативной реализации 0x или 0X добавляется к результату, если преобразованное значение ненулевое.

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

Точность задаёт минимальное количество цифр. Значение по умолчанию — 1. Если преобразованное значение и точность равны ​0​, результат преобразования пуст.

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

Точность задаёт количество цифр после десятичной точки. Значение по умолчанию — 6. В альтернативной реализации десятичная точка выводится, даже если за ней нет цифр. Для бесконечности и нечисловых значений см. примечания.

Н/Д Н/Д
double
double(C99)
Н/Д Н/Д Н/Д Н/Д
long double
e
E
Преобразует число с плавающей точкой в десятичную экспоненциальную запись.

Для e стиля преобразования используется [-]d.ddde±dd.
Для E стиля преобразования используется [-]d.dddE±dd.
Экспонента содержит не менее двух цифр, дополнительных цифр используется только по необходимости. Если значение равно ​0​, экспонента также ​0​. Точность задаёт количество цифр после десятичной точки. Значение по умолчанию — 6. В альтернативной реализации десятичная точка выводится, даже если за ней нет цифр. Для бесконечности и нечисловых значений см. примечания.

Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
a
A

(C99)

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

Для a стиля преобразования используется [-]0xh.hhhp±d.
Для A стиля преобразования используется [-]0Xh.hhhP±d.
Первая шестнадцатеричная цифра не 0 если аргумент — нормализованное число с плавающей точкой. Если значение равно ​0​, экспонента также ​0​. Точность задаёт количество цифр после шестнадцатеричной точки. Значение по умолчанию достаточно для точного представления значения. В альтернативной реализации десятичная точка выводится, даже если за ней нет цифр. Для бесконечности и нечисловых значений см. примечания.

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

Для g стиля преобразования выполняется преобразование со стилем e или f.
Для G стиля преобразования выполняется преобразование со стилем E или F.
Пусть P равно точности, если она ненулевая, 6 если точность не указана или 1 если точность ​0​. Затем, если преобразование со стилем E имело бы экспоненту X:

  • если P > X ≥ −4, преобразование выполняется со стилем f или F и точностью P − 1 − X.
  • иначе, преобразование выполняется со стилем e или E и точностью P − 1.

За исключением случая запрошенного альтернативного представления, конечные нули удаляются, а также десятичная точка, если дробная часть не осталась. Для бесконечности и нечисловых значений см. примечания.

Н/Д Н/Д Н/Д Н/Д Н/Д Н/Д
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, и т. д.) определены в заголовке <inttypes.h> (хотя PRIdMAX, PRIuMAX, и т. д. является синонимом %jd, %ju, и т. д.).

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

После выполнения каждого спецификатора преобразования существует точка последовательности; это позволяет хранить несколько результатов %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 <stdio.h>
#include <stdint.h>
#include <inttypes.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

Ссылки

  • Стандарт 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/w/c/io/fprintf

Spec-Zone.ru

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