Синтаксис спецификации форматирования: printf и wprintf функции

Различные функции printf и wprintf принимают строку формата и необязательные аргументы и создают форматированную последовательность символов для выходных данных. Строка формата не содержит ни одной или содержит несколько директив, которые являются либо литеральными символами для выходных данных, либо закодированными спецификациями преобразования, описывающими способ форматирования аргумента в выходных данных. Эта статья описывает синтаксис для кодирования спецификаций преобразования в строке формата. Список этих функций см. в разделе Потоковый ввод-вывод.

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

%[flags][width][.precision][size]type

Каждое поле спецификации преобразования — это символ или число, указывающее конкретный параметр формата или описатель преобразования. Обязательное поле type определяет тип преобразования, которое применяется к аргументу. Необязательные флаги, ширина и точность полей определяют другие аспекты формата, такие как начальные пробелы или нули, обоснование и отображаемая точность. Поле size указывает размер использованного и преобразованного аргумента.

Базовая спецификация преобразования содержит только символ процента и символ type. Например, %s определяет преобразование строк. Чтобы вывести символ знака процента, используйте %%. Если за символом процента следует символ, который не имеет смысла в поле формата, вызывается обработчик недопустимого параметра. Дополнительные сведения см. в разделе "Проверка параметров".

Важно!

Для обеспечения безопасности и стабильности убедитесь, что строки спецификации преобразования формата не определены конечным пользователем. Например, рассмотрим программу, которая предлагает пользователю ввести имя и сохраняет введенные данные в строковой переменной с именем user_name. Чтобы распечатать user_name, никогда не сделайте следующее:

printf( user_name ); /* Danger! If user_name contains "%s", program will crash */

Вместо этого используйте следующий код:

printf( "%s", user_name );

Примечание.

В Visual Studio 2015 printf были объявлены inline и scanf перемещены в <stdio.h> заголовки и <conio.h> семейства функций. Если вы переносите старый код, вы можете увидеть LNK2019 в связи с этими функциями. Дополнительные сведения см. в журнале изменений Visual C++ 2003 – 2015.

Спецификатор преобразования типов

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

Аргументы, которые следуют за строкой формата, интерпретируются согласно соответствующему символу type и необязательному префиксу size. Преобразования для типов char символов и wchar_t указываются с помощью или Cоднобайтовой и многобайтовой и широкой символьной строки задаются с c помощью s или Sв зависимости от используемой функции форматирования. Аргументы символов и строк, указанные с помощью и cs интерпретируются как charchar* и семейными printf функциями, а также wchar_twchar_t* как и семейными функциями wprintf . Аргументы символов и строк, указанные с помощью и CS интерпретируются как wchar_twchar_t* и семейными printf функциями, а также charchar* как и семейными функциями wprintf . Это поведение зависит от Корпорации Майкрософт. По историческим причинам wprintf функции используют c и s ссылаются на wchar_t символы, а также CS указывают узкие символы.

Целые типы, такие как short, int, longlong longи их unsigned варианты, указываются с помощью d, , i, o, uxи X. Типы с плавающей запятой, такие как floatdouble, efAEи long double, указываются с помощью , a, Fgи .G По умолчанию, если они не изменяются префиксом размера , целочисленные аргументы принужаются к int типу и аргументы с плавающей запятой принуживаются к double. В 64-разрядных системах int используется 32-разрядное значение. Поэтому 64-разрядные целые числа будут усечены при форматировании выходных данных, если не используется префикс ll размера или I64 не используется. Типы указателей, указанные с помощью p размера указателя по умолчанию для платформы.

Примечание.

Только для систем Майкрософт:
Символ Z типа и поведение cсимволов , Csа S также символов типов при их использовании с printf функциями wprintf — расширения Майкрософт. Стандарт ISO C использует и s согласованно используется c для узких символов и строк, а CS также для расширенных символов и строк во всех функциях форматирования.

Символы поля типа

Символ типа Аргумент Формат вывода
c Символ При использовании с функциями printf определяет однобайтовый символ; при использовании с функциями wprintf определяет расширенный символ.
C Символ При использовании с функциями printf определяет расширенный символ; при использовании с функциями wprintf определяет однобайтовый символ.
d Целое Десятичное целое число со знаком.
i Целое Десятичное целое число со знаком.
o Целое Восьмеричное целое число без знака.
u Целое Десятичное целое число без знака.
x Целое Целое число без знака; использует значение "abcdef".
X Целое Целое число без знака; использует значение "ABCDEF".
e С плавающей запятой Подписанное значение с формой [-]dddde[+-|]dd[d], где d — одна десятичная цифра, dddd — одна или несколько десятичных цифр в зависимости от указанной точности или шести по умолчанию, а dd[d] — две или три десятичные цифры в зависимости от формата вывода и размера экспонента.
E С плавающей запятой Идентичен формату e , за исключением того, что E вместо e представления экспонента.
f С плавающей запятой Подписанное значение, которое имеет форму [-]dddd.dd, где d имеет одну или несколько десятичных цифр. Количество цифр перед десятичной запятой зависит от величины числа, а количество знаков после десятичной запятой зависит от указанной точности либо используется шесть по умолчанию.
F С плавающей запятой Идентичен формату, за исключением бесконечности и выходных f данных NaN.
g С плавающей запятой Подписанные значения отображаются в f формате или e формате, в зависимости от того, что является более компактным для заданного значения и точности. Формат e используется только в том случае, если экспонент значения меньше -4 или больше или равен аргументу точности . Нули в конце отбрасываются, а десятичная запятая отображается только в том случае, если за ней следует хотя бы одна цифра.
G С плавающей запятой Идентичен форматуg, за исключением того, что eEвместо этого представляет экспонент (где это необходимо).
a С плавающей запятой Подписанное шестнадцатеричное значение двойной точности с плавающей запятой, которое имеет форму []0xhh+|-p[]dd, где h.hh являются шестнадцатеричными цифрами (с использованием строчных букв) мантисса, и dd — один или несколько цифр для экспонента.- Точность определяет количество цифр после запятой.
A С плавающей запятой Подписанное шестнадцатеричное значение двойной точности с плавающей запятой, которое имеет форму [-]0XhhhP[-+|]dd, где h.hhhh являются шестнадцатеричными цифрами (используя буквы букв) мантисса, и dd — один или несколько цифр для экспонента. Точность определяет количество цифр после запятой.
n Указатель на целое число Число символов, которые успешно записаны на данный момент в поток или буфер. Это значение хранится в целом числе, адрес которого указан в качестве аргумента. Размер целочисленного значения, на которое ссылается указатель, управляется префиксом спецификации размера аргумента. Описатель n отключен по умолчанию. Дополнительные сведения см. в примечании по безопасности.
p Тип указателя Отображение аргумента в виде адреса в шестнадцатеричных цифрах.
s Строка При использовании с функциями printf определяет строку однобайтовых или многобайтовых символов; при использовании с функциями wprintf определяет строку расширенных символов. Символы отображаются до первого нулевого символа или до тех пор, пока не будет достигнуто значение precision.
S Строка При использовании с функциями printf определяет строку расширенных символов; при использовании с функциями wprintf определяет строку однобайтовых или многобайтовых символов. Символы отображаются до первого нулевого символа или до тех пор, пока не будет достигнуто значение precision.
Z Структура ANSI_STRING или UNICODE_STRING VS 2013 и более ранних версий
Когда адрес ANSI_STRING или UNICODE_STRING структура передается в качестве аргумента, отображает строку, содержащуюся в буфере, на которую указывает Buffer поле структуры. Используйте префикс модификатора размера для указания аргумента wUNICODE_STRING, например%wZ. Поле Length структуры должно содержать значение длины строки в байтах. Поле MaximumLength структуры должно содержать значение длины буфера в байтах.

Универсальная среда выполнения C (UCRT)
Существует известная проблема в UCRT, которая в настоящее время поддерживается для обеспечения совместимости. S Как и описатель, Z описатель без префикса модификса размера ссылается на UNICODE_STRING использование узкой функции печати (напримерprintf) и ANSI_STRING при использовании широкой функции печати (напримерwprintf).
Вместо этого Zиспользуйте для hZ указания ANSI_STRINGзначения . wZ (или lZ) можно по-прежнему использовать для указания UNICODE_STRINGзначения .

Как правило, Z символ типа используется только в функциях отладки драйверов, использующих спецификацию преобразования, например dbgPrint и kdPrint.

В Visual Studio 2015 и более поздних версиях, если аргумент, соответствующий описатель преобразования с плавающей запятой (a, , fEeFAg) Gявляется бесконечным, неопределенным или NaN, форматированные выходные данные соответствуют стандарту C99. В этой таблице перечислены форматированные выходные данные.

Значение Выходные данные
Infinity inf
Несигнальное значение NaN nan
Сигнальное значение NaN nan(snan)
Неопределенное значение NaN nan(ind)

Любой из этих строк может быть префиксирован знаком. Если символ описателя преобразования type с плавающей запятой является прописной буквой, выходные данные форматируются также прописными буквами. Например, если спецификатором формата является %F вместо %f, бесконечность форматируется как INF вместо inf. Функции scanf также могут анализировать эти строки, поэтому эти значения могут совершать круговой путь через функции printf и scanf.

До выхода Visual Studio 2015 в среде CRT использовался другой нестандартный формат для выходных данных значений бесконечности, неопределенных значений и значений NaN.

Значение Выходные данные
+ Бесконечность 1.#INFслучайные цифры
-Бесконечности -1.#INFслучайные цифры
Неопределенное (то же, что и не число без вызова исключения) цифра.#INDслучайные цифры
Не число цифра.#NANслучайные цифры

Любой из этих строк может быть префиксирован знаком и может быть отформатирован по-разному в зависимости от ширины поля и точности, иногда с необычными эффектами. Например, печать1.#J, printf("%.2f\n", INFINITY) так как #INF будет "округлено" до двух цифр точности.

Примечание.

Если аргумент, который соответствует %s или %S, или поле Buffer аргумента, который соответствует %Z, является указателем NULL, отображается значение "(NULL)".

Примечание.

Во всех экспоненциальных форматах минимальное отображаемое количество цифр показателя степени по умолчанию равно двум (три используются только при необходимости). С помощью _set_output_format функции можно задать число цифр, отображаемых в три для обратной совместимости с кодом, написанным для Visual Studio 2013 и раньше.

Важно!

%n Так как формат по сути небезопасн, он отключен по умолчанию. При %n обнаружении в строке формата вызывается обработчик недопустимых параметров, как описано в разделе проверки параметров. Сведения о включении %n поддержки см. в статье _set_printf_count_output.

Директивы флагов

Первое необязательное поле в спецификации преобразования содержит директивы флага. Это поле содержит ноль или несколько символов флагов, которые указывают выходное обоснование и контрольные выходные данные знаков, пустые значения, начальные нули, десятичные точки и шестнадцатеричные префиксы. В спецификации преобразования может быть указано несколько директив флагов, и символы флагов могут размещаться в любом порядке.

Символы флагов

Флаг Значение По умолчанию
- Выравнивание результата по левому краю в пределах заданной ширины поля. Выравнивание по правому краю.
+ Используйте знак (+ или -), чтобы префиксировать выходное значение, если оно имеет подписанный тип. Знак отображается только для отрицательных значений со знаком –.
0 Если ширина префиксирована 0, начальные нули добавляются до достижения минимальной ширины. Если указаны одновременно 0 и -, знак 0 игнорируется. Если 0 задан для целочисленного формата (i, , ux, X, , o) dи спецификации точности также присутствуют ( например, %04.d0 игнорируются). Если 0 задано для a формата с A плавающей запятой, начальные нули добавляются в мантиссу после 0x префикса или 0X префикса. Без заполнения.
пустой (" ") Используйте пустое значение, чтобы префиксировать выходное значение, если оно подписано и положительно. Пустой префикс игнорируется, если одновременно с ним присутствует флаг +. Пустой префикс не отображается.
# Если он используется с параметром o, xили X форматом#, флаг использует 00x(или 0Xсоответственно) префикс любого выходного значения, отличного от нуля. Префикс не отображается.
При использовании с флагом e, E, faFA или форматированием # флаг заставляет выходное значение содержать десятичную точку. Десятичный разделитель появляется, только если после него есть цифры.
Если используется в сочетании с форматом g или G, флаг # принудительно добавляет десятичный разделитель к выходному значению и запрещает отбрасывать конечные нули.

Флаг игнорируется в сочетании с форматами c, d, i, u и s.
Десятичный разделитель появляется, только если после него есть цифры. Конечные нули отбрасываются.

Спецификация ширины

В спецификации преобразования необязательное поле спецификации ширины отображается после любых символов флага. Аргумент width — это неотрицательное целое число, которое управляет минимальным числом символов, которые являются выходными. Если количество символов в выходном значении меньше заданной ширины, к значениям слева или справа (в зависимости от того, определен ли флаг выравнивания по левому краю (-)) добавляются пробелы, в количестве, необходимом для достижения минимальной ширины. Если width префикс равен 0, начальные нули добавляются в целочисленные или с плавающей запятой преобразования до достижения минимальной ширины, за исключением случаев, когда преобразование равно бесконечности или NaN.

Спецификация ширины никогда не вызывает усечения значения. Если число символов в выходном значении больше указанной ширины или если width оно не указано, все символы значения являются выходными, при условии точной спецификации.

Если в качестве спецификации ширины указана звездочка (*), значение ширины задается аргументом int из списка аргументов. Аргумент width должен предшествовать значению, отформатируемого в списке аргументов, как показано в этом примере:

printf("%0*d", 5, 3); /* 00003 is output */

Отсутствующее или небольшое width значение в спецификации преобразования не приводит к усечению выходного значения. Если результат преобразования превышает width значение, поле расширяется, чтобы содержать результат преобразования.

Спецификация точности

В спецификации преобразования третье необязательное поле является спецификацией точности. Он состоит из периода (.), за которым следует неотрицательное целое число, которое в зависимости от типа преобразования указывает количество строковых символов, число десятичных разрядов или число значимых цифр, которые должны быть выходными.

В отличие от спецификации ширины, спецификация точности может вызывать либо усечение выходного значения, либо округление значения с плавающей запятой. Если precision задано значение 0, а преобразованное значение равно 0, результат не выводит символов, как показано в этом примере:

printf( "%.0d", 0 ); /* No characters output */

Если спецификация точности представляет собой звездочку (*), аргумент int из списка аргументов предоставляет значение. В списке аргументов аргумент precision должен предшествовать форматируемому значению, как показано в следующем примере:

printf( "%.*f", 3, 3.14159265 ); /* 3.142 output */

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

Влияние значений точности на тип

Тип Значение По умолчанию
a, A Точность определяет количество цифр после запятой. Точность по умолчанию — 13. Если точность равна 0, десятичная запятая не выводится, если не используется флаг #.
c, C Точность не применяется. Символ выводится.
d, i, o, u, x, X Точность определяет минимальное выводимое количество цифр. Если количество цифр в аргументе меньше значения precision, выходное значение дополняется слева нулями. Значение не усечено, если число цифр превышает точность. Точность по умолчанию — 1.
e, E Выводимое количество знаков дробной части задается спецификацией точности. Последняя выводимая цифра округляется. Точность по умолчанию — 6. Если точность равна 0 или период (.) отображается без числа после него, десятичная точка не выводится.
f, F Значение точности задает количество цифр после десятичной запятой. Если десятичная запятая присутствует, перед ней присутствует по крайней мере одна цифра. Значение округляется до соответствующего количества цифр. Точность по умолчанию — 6. Если точность равна 0 или если период (.) отображается без числа после него, десятичная точка не выводится.
g, G Точность определяет максимальное выводимое количество значащих цифр. Выводятся шесть значащих цифр, а конечные нули усекаются.
s, S Точность определяет максимальное количество выводимых символов. Символы, выходящие за рамки precision, не выводятся. Символы печатаются до тех пор, пока не будет найден пустой символ.

Спецификация размера аргумента

В спецификации преобразования поле size — это модификатор длины аргумента для описателя преобразования type. Префиксы поля размера в поле типа , jhhh, l , (строчные буквы), L, Iwtzll(верхний регистр i), I32и I64—укажите "размер" соответствующего аргумента — длинный или короткий, 32-разрядный или 64-разрядный, однобайтовый или широкий символ в зависимости от того, что они изменяют. Эти префиксы размера используются с символами type в семействах функций printf и wprintf для определения интерпретации размеров аргументов, как показано в следующей таблице. Поле size является необязательным для некоторых типов аргументов. Если префикс размера не указан, модуль форматирования использует целые аргументы, например подписанные или не подписанные char, short, int, long и типы перечисления как 32-разрядные типы int, а аргументы float, double и long double с плавающей запятой используются как 64-разрядные типы double. Такое поведение соответствует правилам повышения уровня аргументов по умолчанию для списков аргументов переменных. Дополнительные сведения о продвижении аргументов см. в разделе Многоточие и аргументы по умолчанию в выражениях Postfix. В 32-разрядных и 64-разрядных системах спецификация преобразования 64-разрядного целочисленного аргумента должна содержать префикс ll размера или I64. В противном случае поведение модуля форматирования не определено.

Некоторые типы имеют разный размер в 32-разрядном и 64-разрядном коде. Например, size_t на 32 бита длиннее в коде, скомпилированном для x86, и на 64 бита длиннее в коде, скомпилированном для x64. Чтобы создать код форматирования для типов с переменным количеством байт, не зависящий от платформы, можно использовать модификатор размера аргумента с переменным количеством байт. Вместо этого используйте модификатор размера 64-разрядного аргумента и явно повысить тип аргумента переменной ширины до 64 бит. Модификатор размера аргумента (Iв верхнем регистре i) обрабатывает целые аргументы переменной ширины, но рекомендуется использовать модификаторы типа jtz и модификаторы для переносимости.

Префиксы размера для описателей типов формата printf и wprintf

Чтобы указать Используемый префикс Со спецификатором типа
char
unsigned char
hh d, i, o, u, x или X
short int
short unsigned int
h d, i, o, u, x или X
__int32
unsigned __int32
I32 d, i, o, u, x или X
__int64
unsigned __int64
I64 d, i, o, u, x или X
intmax_t
uintmax_t
j или I64 d, i, o, u, x или X
long double l (строчная буква L) или L a, A, e, E, f, F, g или G
long int
long unsigned int
l (строчная L) d, i, o, u, x или X
long long int
unsigned long long int
ll (строчные буквы LL) d, i, o, u, x или X
ptrdiff_t t или I (верхний регистр i) d, i, o, u, x или X
size_t z или I (верхний регистр i) d, i, o, u, x или X
Однобайтовый символ h c или C
Расширенный символ l (строчная буква L) или w c или C
Строка однобайтовых символов h s, S или Z
Строка расширенных символов l (строчная буква L) или w s, S или Z

Типы ptrdiff_t и size_t являются __int32 или unsigned __int32 на 32-разрядных платформах и __int64 или unsigned __int64 на 64-разрядных платформах. I Префиксы (верхний регистр i), jtи z размеры принимают правильную ширину аргумента для платформы.

В Visual C++ хотя long double является отдельным типом, он имеет то же внутреннее представление, что и тип double.

Описатель hc или описатель типов является синонимом c функций printf и функций wprintfChC. Описатель lcтипов или wC описатель типов является синонимом функций printfC и функций cwprintf. lCwc Описатель hs или описатель типов является синонимом s функций printf и функций wprintfShS. Описатель lsтипов или wS описатель типов является синонимом S функций printf и функций swprintf. lSws

Примечание.

Только для систем Майкрософт:
I Префиксы модификатора размера аргументов (прописные буквы i), I32I64а также w префиксы размера аргументов являются расширениями Майкрософт и не совместимы с ISO C. Префикс h при использовании с данными типа char и l префиксом (строчным регистром L) при использовании с данными типа double являются расширениями Майкрософт.

См. также

printf, _printf_l, wprintf, _wprintf_l
printf_s, _printf_s_l, wprintf_s, _wprintf_s_l
printf_p Позиционные параметры