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) |
Загружает данные из заданных мест, преобразует их в эквиваленты строковых символов и записывает результаты в различные стоки/потоки:
stdout.stream.buffer. Поведение не определено, если записываемая строка (плюс завершающий нулевой символ) превышает размер массива, на который указывает buffer.buffer. Максимум bufsz - 1 символов будут записаны. Результирующая строка символов будет завершена нулевым символом, если bufsz не равно нулю. Если bufsz равно нулю, ничего не записывается и buffer может быть указателем на нуль, но значение возврата (число байтов, которые были бы записаны, не включая нулевой терминатор) всё равно вычисляется и возвращается.-
- спецификатор преобразования
%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 | Выводит один символ. Аргумент сначала преобразуется в | Н/Д | Н/Д |
int |
wint_t | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
s | Выводит строку символов Аргумент должен быть указателем на начальный элемент массива символов. Точность задаёт максимальное количество байтов для вывода. Если Точность не указана, выводится каждый байт до, но не включая, первого нулевого терминатора. Если используется спецификатор l, аргумент должен быть указателем на начальный элемент массива | Н/Д | Н/Д |
char* |
wchar_t* | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д |
di | Преобразует целое со знаком в десятичное представление [-]dddd. Точность задаёт минимальное количество цифр. Значение по умолчанию — |
signed char |
short |
int |
long |
long long |
целое со знаком size_t
| Н/Д | ||
o | Преобразует целое без знака в восьмеричное представление oooo. Точность задаёт минимальное количество цифр. Значение по умолчанию — |
unsigned char |
unsigned short |
unsigned int |
unsigned long |
unsigned long long |
беззнаковая версия ptrdiff_t
| Н/Д | ||
xX | Преобразует целое без знака в шестнадцатеричное представление hhhh. Для | Н/Д | ||||||||
u | Преобразует целое без знака в десятичное представление dddd. Точность задаёт минимальное количество цифр. Значение по умолчанию — | Н/Д | ||||||||
fF | Преобразует число с плавающей точкой в десятичную запись вида [-]ddd.ddd. Точность задаёт количество цифр после десятичной точки. Значение по умолчанию — | Н/Д | Н/Д |
double |
double(C99)
| Н/Д | Н/Д | Н/Д | Н/Д |
long double |
eE | Преобразует число с плавающей точкой в десятичную экспоненциальную запись. Для | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
aA (C99) | Преобразует число с плавающей точкой в шестнадцатеричную экспоненциальную запись. Для | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
gG | Преобразует число с плавающей точкой в десятичную или экспоненциальную десятичную запись в зависимости от значения и точности. Для
За исключением случая запрошенного альтернативного представления, конечные нули удаляются, а также десятичная точка, если дробная часть не осталась. Для бесконечности и нечисловых значений см. примечания. | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | Н/Д | |||
n | Возвращает количество записанных символов на данный момент вызовом этой функции. Результат записывается в значение, на которое указывает аргумент. В спецификации не должно быть флагов, ширины поля или точности. |
signed char* |
short* |
int* |
long* |
long long* |
знаковое size_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 в рамках одного вызова.
Если спецификация преобразования недействительна, поведение не определено.
Значение возврата
buffer (не считая завершающего нулевого символа), или отрицательное значение, если произошла ошибка кодирования (для спецификаторов преобразования строк и символов)buffer , если bufsz был пропущен, или отрицательное значение, если произошла ошибка кодирования (для спецификаторов преобразования строк и символов)buffer, не считая нулевого символа (который всегда записывается, если buffer не является нулевым указателем и bufsz не равно нулю и не больше RSIZE_MAX), или ноль при нарушениях ограничений во время выполнения, и отрицательное значение при ошибках кодирования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
См. также
|
(C95)(C95)(C95)(C11)(C11)(C11)(C11) | печатает форматированный вывод символов широкого типа в stdout, потоке файла или буфере (функция) |
|
(C99)(C11)(C11)(C11)(C11) | печатает форматированный вывод в stdout, поток файла или буферс использованием списка аргументов переменной длины (функция) |
| записывает строку символов в поток файла (функция) |
|
|
(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