- HuMan: printf
- Представление аргумента
- Форматы команды printf
- Модификаторы форматов
- Модификаторы:
- Альтернативный формат для чисел
- Точность разрешения
- Управляющие символы языка Си, работающие с командой printf
- Еще несколько примеров
- Опции команды printf
- Опция -v ПЕРЕМЕННАЯ_ОКРУЖЕНИЯ
- Примечание:
- Резюме команды printf
- Linux printf перенос строки
- Возвращаемое значение
- Структура строки параметров
- Флаги
- Ширина поля
- Точность
- Модификаторы длины
- Тип преобразования
- ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
- СООТВЕТСТВИЕ СТАНДАРТАМ
- ПРИМЕЧАНИЯ ПО ИСТОРИИ
- НАЙДЕННЫЕ ОШИБКИ
- 23. Оператор printf — перенос символьной строки
- 24. Оператор printf — вывод текстовых строк по near- и far-указателям
- 25. Оператор printf — работа с Esc-символами
- Команда printf в Bash
- Команда printf
- Символы с экранированием обратной косой чертой
- Технические характеристики преобразования
- Спецификатор преобразования типа
- Директива флагов
- Директива по ширине
- Директива о точности
- Выводы
HuMan: printf
Команда printf выводит АРГУМЕНТ на стандартный вывод (как правило, экран дисплея), используя при этом определенный ФОРМАТ.
Эта команда была создана для замены всем знакомой команды echo (настолько древней, что даже имя ее автора не известно).
Возможности команды echo ограничены, кроме того, в разных ветках Unix’а оказались разные ее версии, что приводит к несовместимости.
Поэтому Posix рекомендует пользоваться командой printf.
Самое первое, что следует прояснить: по умолчанию команда printf не переводит строку по завершении. Это выглядит так:
Следующее приглашение командной строки находится на той же самой строке что и вывод предыдущей команды. Это очень неудобно, поэтому в ФОРМАТ приходится добавлять символ новой строки (\n):
Приглашение переехало на новую строку, и все обрело привычный вид. В дальнейшем я не стану приводить приглашение целиком, ограничусь знаком доллара.
Вот как выглядит команда printf в виде, полностью дублирующем команду echo:
Обратите внимание, что мы взяли аргумент в кавычки, чтобы получить его в виде одной строки. Если бы мы этого не сделали, то имели бы столбик, так как программа воспринимает выражения, разделенные пробелом, как множественные аргументы, и обрабатывает каждый в соответствии с заданным форматом:
Если нам нужно использовать команду printf для просмотра переменных окружения, то кавычки не нужны:
Если же мы возьмем аргумент в кавычки, то он будет воспринят просто как выражение и воспроизведен дословно:
Но довольно о замене команды echo, займемся непосредственно командой printf.
Представление аргумента
0N Восьмеричное число. Например 024.
0xN и 0XN Шестнадцатеричные числа. Например 0?41.
«А (обычные кавычки перед любой буквой) Интерпретируется как кодовый номер этой буквы в текущей кодировке. С кириллицей не работает.
‘А (одинарные кавычки перед любой буквой) Интерпретируется как кодовый номер этой буквы в текущей кодировке. С кириллицей не работает.
Форматы команды printf
ФОРМАТ пишется в командной строке непосредственно после самой команды и заключается в кавычки — двойные или одинарные. Собственно говоря, кавычки нужны не всегда, но лучше их ставить, во избежание недоразумений. Это полезная привычка. (А ведь большинство привычек — вредные).
%b Рассматривает аргумент как строку, при этом интерпретирует все управляющие символы, содержащиеся в ней.
%s Рассматривает аргумент как просто как строку.
%c Рассматривает аргумент как символ, при этом берется первый символ выражения или строки.
%q Преобразует строку к виду, пригодному к использованию в качестве ввода в шелл.
Здесь необходимы пояснения. Допустим, мы хотим напечатать на экране фразу
Ваш,
Алексей Дмитриев
Для этого дадим следующую команду:
А теперь вместо формата %b применим формат %q:
Кажется, произошла какая-то ошибка или сбой. Но это не так; подставим вывод команды в качестве аргумента команды printf ‘%b\n’ , но уже безо всяких дополнительных кавычек (все необходимые кавычки содержатся в выводе команды):
Больше того, этот же вывод можно использовать в качестве аргумента для других команд, скажем echo -e (опция -e позволяет команде echo интерпретировать специальные символы, в частности символ новой строки (\n):
Вот какой интересный формат %q! Однако продолжим.
Дальше идут всевозможные форматы представления чисел.
%i То же, что и предыдущее.
%o Представляет аргумент в виде не имеющего знака восьмеричного числа.
%x Представляет аргумент в виде не имеющего знака шестнадцатеричного числа. Буквы пишутся в нижнем регистре.
%X Представляет аргумент в виде не имеющего знака шестнадцатеричного числа, при этом буквы пишутся в верхнем регистре.
%f Интерпретирует аргумент как число с плавающей запятой.
%e Интерпретирует аргумент с удвоенной точностью (double precision), при этом выводит его в формате +/-e .
%E То же, что и предыдущее, только с заглавной буквой Е.
Вот и все форматы, я привел их для встроенной в bash команды printf.
Модификаторы форматов
(С кириллицей не работает).
Модификаторы:
# Альтернативный формат для чисел, см. ниже.
— Выравнивание текста по левому краю (стандарно — по правому краю)
0 Дополняет числа нулями, а не пробелами. Применяется при заданной ширине колонки (в примере 50). Пример:
space Дополняет положительные числа пробелами, а отрицательные знаками «минус» (-).
+ Пишет все числа со знаками плюс или минус.
Альтернативный формат для чисел
%#x, %#X Шестнадцатеричные числа пишутся с 0х или 0Х впереди, если они сами не нулевые:
%#g, %#G Числа с плавающей запятой пишутся с последующими нулями, в количестве, определяемом данным разрешением. Обычно последующие нули не пишутся:
%# со всеми числовыми форматами, кроме d, o, x, X Всегда ставит десятичную запятую, даже если знаков после запятой нет:
Точность разрешения
Внимание: не прозевайте точку в записи формата!
Можно вместо числа знаков поставить астериск, тогда количество знаков ставится перед самим аргументом:
Для строк точность разрешения определяет максимальное число выводимых символов (максимальную ширину колонки текста).
Для целых чисел — задает число выводимых знаков (добавляет нули).
Управляющие символы языка Си, работающие с командой printf
\NNN Символ с восьмеричным значением NNN (от 1 до 3 цифр)
\a Звуковой сигнал
\c Не производить дальнейшую обработку данных
\f Перевод страницы
\r Возврат каретки
\v Вертикальная табуляция
\xHH Символ с шестнадцатеричным кодом HH (1 или 2 цифры)
\uHHHH Символ Unicode (ISO/IEC 10646) с шестнадцатеричным кодом HHHH (4 цифры)
\UHHHHHHHH Символ Unicode с шестнадцатеричным кодом HHHHHHHH (8 цифр)
Еще несколько примеров
2. Вывести десятичное число в восьмеричной форме:
3. Узнать кодовый номер буквы А (англ):
4. Пример, могущий служить домашним заданием:
Кто понял, в чем тут дело, сообщите мне, пожалуйста. Я лично не понял.
Опции команды printf
Опция -v ПЕРЕМЕННАЯ_ОКРУЖЕНИЯ
Хорошо, что в начале статьи я привел пример, в котором была записана моя $PATH, поэтому смог восстановить.
Опции —help и —version общеизвестны и рассмотрены не будут.
Примечание:
Резюме команды printf
Должен предупредить, что собрал в этой статье все, что сумел «нарыть» по поводу всех версий этой команды. Поэтому некоторые варианты могут не срабатывать в ваших версиях.
Источник
Linux printf перенос строки
Функции vprintf , vfprintf , vsprintf , vsnprintf эквивалентны соответствующим функциям printf , fprintf , sprintf , snprintf , исключая то, что они вызываются с va_list, а не с переменным количеством аргументов. Эти функции не вызывают макрос va_end , и поэтому значение ap после вызова неопределенно. Приложение может позже само вызвать va_end(ap) .
Эти восемь функций выводят данные в соответствии со строкой format , которая определяет, каким образом последующие параметры (или доступные параметры переменной длины из stdarg (3)) преобразуют поток вывода.
Возвращаемое значение
Структура строки параметров
В некоторых цифровых преобразованиях используется символ десятичной точки или символ тысячной группировки `,’. Текущий символ зависит от переменной LC_NUMERIC. Стандарт POSIX по умолчанию использует символ `.’ и не поддерживает символ группировки. Таким образом, выводит `1234567.89′ в стандарте POSIX, `1234567,89′ в локализации nl_NL и `1.234.567,89′ в локализации da_DK.
Флаги
Пять флагов, описанных выше, определены в стандарте C. В стандарте SUSv2 определен один дополнительный флаг. ‘ При десятичных преобразованиях ( i , d , u , f , g , G ) данные группируются символом тысячной группировки, если информация локализации не указывает на это. Обратите внимание, что многие версии gcc не могут распознать эту опцию и выводят соответствующее предупреждение. SUSv2 не включает %’F.
glibc 2.2 добавит в будущем этот флаг. I При преобразовании целых десятичных чисел ( i , d , u ) вывод использует локальное представление цифр (например арабские цифры). Однако он не включает все локальные определения как определено в outdigits . См. http://sources.redhat.com/ml/libc-alpha/2000-08/msg00230.html
Ширина поля
Точность
Модификаторы длины
SUSv2 располагает информацией только о модификаторах длины h (с hd , hi , ho , hx , hX , hn ); l (с ld , li , lo , lx , lX , ln , lc , ls ) и L (с Le , LE , Lf , Lg , LG ).
Тип преобразования
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
Печатает дату и вpемя в фоpме `Sunday, July 3, 10:02′, где weekday и month являются указателями на стpоку:
Многие стpаны используют поpядок отобpажения даты в виде «день, месяц, год». Следовательно, междунаpодная веpсия должна отображать значений в pазличных стандаpтах: где format зависит от локальных установок и может менять аpгументы. Оперируя значениями , можно получить `Воскресенье, 3. Июль, 10:02′.
Указание достаточно большой строки и ее вывод (код корректен для обеих версий: glibc 2.0 и glibc 2.1):
СООТВЕТСТВИЕ СТАНДАРТАМ
Что касается возвpащаемого значения snprintf , то стандаpты SUSv2 и C99 пpотивоpечат дpуг дpугу: когда snprintf вызывается с size =0 , тогда SUSv2 пpедусматpивает неопpеделенную величину возвpата, меньшую единицы, а C99 устанавливает в этом случае str pавной NULL и возвpащает значение (как обычно) в виде числа символов, размер которых в выходной стpоке был бы достаточным.
Библиотека Linux libc4 располагает информацией о пяти стандартных флагах C. Она также знает о модификаторах длины g, l, L и преобразованиях cdeEfFgGinopsuxX, где F является синонимом f. Дополнительно она принимает D, O, U как синонимы ld, lo, lu. (Это плохо и привело позже к серьезной ошибке, когда исчезла поддержка %D.) Зависимые от локали символы системы исчисления, разделители тысяч, бесконечность, %m$ и *m$ не поддерживаются.
Библиотека Linux libc5 располагает информацией о пяти стандартных флагах C и флагах локализации, %m$ и *m$, о модификторах длины h,l,L,Z,q, но соотносит типы L и q с long double и сверхдлинным целым (это ошибка). Данная библиотека больше не распознает FDOU, но содержит новый символ преобразования m , который выводит strerror(errno) .
glibc 2.0 сейчас поддерживает символы C и S.
К glibc 2.1 добавлены модификаторы длины hh,j,t,z и символы преобразования a,A. В glibs 2.2 добавлены символы преобразования F с семантикой C99 и флаг I.
ПРИМЕЧАНИЯ ПО ИСТОРИИ
НАЙДЕННЫЕ ОШИБКИ
Библиотека Linux libc4.[45] не имеет функции snprintf , однако предоставляет libbsd, содержащую snprintf , эквивалентную sprintf , то есть игнорирующую аргумент size . Таким образом, использование snprintf с ранними версиями libc4 ведет к серьезным проблемам с безопасностью.
Код типа printf( foo ); часто приводит к ошибке, если foo может содержать символ %. Если в foo записан непроверенный ввод пользователя, то содержит foo может содержать %n, и это вызовет запись в память и создание бреши в безопасности.
Некоторые преобразования чисел с плавающей запятой в ранних версиях libc4 приводили к утечкам памяти.
Источник
23. Оператор printf — перенос символьной строки
При использовании в программе функции printf может оказаться, что выводимая функцией символьная строка не помещается на текущей строке исходного кода. В таких случаях следует поместить знак обратной наклонной черты (\) в конце текста на текущей строке, продолжив текст с начала следующей строки, как показано ниже:
printf(«Эта строка слишком длинная и не может \
поместиться на одной строке.»);
Примечание: При переносе текста не следует включать пробелы в начало текста на следующей строке. Если такие пробелы имеются, то они включаются Си-компилятором в текстовую строку.
24. Оператор printf — вывод текстовых строк по near- и far-указателям
В разделе «Управление памятью» near- и far-указатели (ближние и удаленные соответственно) обсуждаются достаточно подробно. При использовании в программе строковых far-указателей естественно возникают случаи, когда требуется вывести содержимое строки с помощью printf. Однако, как станет известно в дальнейшем из этой книги, при передаче,fаг-указателя функции, ожидающей короткий (near) адрес, происходит ошибка. Если все же требуется отобразить содержимое строки по ее far-указателю, то следует информировать функцию printf, что используется far-указатель. Для этого надо поместить прописную букву F (для far) сразу после символа %:
В этом случае вызов функции printf будеткорректным. Аналогично можно информировать функцию printf, что ей передается строка с ближним (near) указателем, задавая прописную букву N. Однако, поскольку пеаг-указатели-подразумеваются по умолчанию, спецификаторы формата %Ns и %s означают одно и то же. В следующей программе NEAR_FAR.С показывается использование спецификаторов формата %Fs и %Ns:
char *near_title = «1001 совет по C/C++»;
char far *far_title = «1001 совет по C/C++»;
printf(«Название книги: %Ns\n», near_title);
printf(«Название книги: %Fs\n», far_title);
25. Оператор printf — работа с Esc-символами
При работе с символьными строками часто возникает потребность в использовании некоторых специальных символов, таких как табуляция, возврат каретки или перевод строки. Для обеспечения удобного включения таких символов в строки символов (предназначенные, например, для использования в printf) язык Си определяет набор так называемых Escape-символов (обозначаемых также Esc-символы). Например, во многих программах, представленных в этой книге, следующим образом используется символ перевода строки для продолжения вывода с начала новой строки:
printf(«Строка 1\nСтрока 2\nСтрока З») ;
В табл. 1представлены Esc-символы, которые могут быть использованы в символьных строках (и, следовательно, в выводе printf).
Таблица 1. Esc-символы, определенные в Си
\а ASCII-символ звукового сигнала
\b Возврат на символ
\f Символ перевода формата
\n Символ перевода строки
\r Символ возврата каретки
\t Горизонтальная табуляция
\v Вертикальная табуляция
\\ Символ обратная наклонная черта
\nnn ASCII-значение в восьмиричном виде
\xnnn ASCII-значение в шестнадцатиричном виде
Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.
Источник
Команда printf в Bash
Обычно при написании сценариев bash мы используем echo для вывода на стандартный вывод. echo — простая команда, но ее возможности ограничены.
Чтобы иметь больше контроля над форматированием вывода, используйте команду printf .
Команда printf форматирует и печатает свои аргументы, аналогично printf() в Си.
Команда printf
printf — это оболочка, встроенная в Bash и другие популярные оболочки, такие как Zsh и Ksh. Также существует отдельный двоичный файл /usr/bin/printf , но встроенная версия оболочки имеет приоритет. Мы рассмотрим встроенную в Bash версию printf .
Синтаксис команды printf следующий:
Параметр -v указывает printf не печатать вывод, а назначать его переменной.
format представляет собой строку, которая может содержать три разных типа объектов:
- Обычные символы, которые просто выводятся как есть.
- Символы с обратной косой чертой, которые интерпретируются и затем печатаются.
- Спецификации преобразования, которые описывают формат и заменяются значениями соответствующих аргументов, следующих за строкой формата.
Команда принимает любое количество arguments . Если указано больше arguments чем спецификаторов format строка format повторно используется для использования всех аргументов. Если передано меньше arguments чем указателей формата, дополнительные описатели числового формата устанавливаются на нулевое значение, а описатели строкового формата устанавливаются на пустую строку.
Ниже приведены несколько моментов, которые следует учитывать при передаче аргументов команде printf :
- Оболочка заменит все переменные, сопоставление подстановочных знаков и специальные символы перед передачей аргументов команде printf .
- При использовании одинарных кавычек » буквальное значение каждого символа, заключенного в кавычки, будет сохранено. Переменные и команды расширяться не будут.
Типичный пример использования printf выглядит так:
Строка Open issues: %snClosed issues: %sn — это format а «34» и «65» — аргументы. Строка формата содержит два символа новой строки ( n ) и два спецификатора формата ( %s ), которые заменяются аргументами.
Команда printf не добавляет символ новой строки ( n ) в конец строки.
Символы с экранированием обратной косой чертой
Экранированные символы обратной косой черты интерпретируются при использовании в строке формата или в аргументе, соответствующем спецификатору преобразования %b . Вот список наиболее распространенных escape-символов:
- \ — отображает обратную косую черту.
- b — отображает символ возврата.
- n — отображает новую строку.
- r — отображает возврат каретки.
- t — отображает горизонтальную вкладку.
- v — отображает вертикальную вкладку.
Технические характеристики преобразования
Спецификация преобразования имеет следующую форму:
Каждая спецификация преобразования помечается знаком процента ( % ), включает необязательные модификаторы и заканчивается одной из следующих букв, представляющих тип данных ( specifier ) соответствующего аргумента: aAbcdeEfgGioqsuxX .
Спецификатор преобразования типа
Преобразование типа specifier это символ , который указывает , как интерпретировать соответствующий аргумент. Этот символ является обязательным и помещается после необязательных полей.
Ниже приведен список, в котором показаны все преобразования типов и их назначение:
- %b — распечатать аргумент при расширении escape-последовательностей с обратной косой чертой.
- %q — распечатать аргумент, заключенный в кавычки, повторно используемый в качестве входных данных.
- %d , %i — вывести аргумент как десятичное целое число со знаком.
- %u — распечатать аргумент как десятичное целое число без знака.
- %o — вывести аргумент в виде восьмеричного целого числа без знака.
- %x , %X — распечатать аргумент как шестнадцатеричное целое число без знака. %x печатает строчные буквы, а %X печатает прописные.
- %e , %E — распечатать аргумент как число с плавающей запятой в экспоненциальной записи. %e печатает буквы в нижнем регистре, а %E верхнем регистре.
- %a , %A — распечатать аргумент как число с плавающей запятой в шестнадцатеричной дробной нотации. %a печатает буквы в нижнем регистре, а %A верхнем регистре.
- %g , %G — Распечатать аргумент как число с плавающей запятой в нормальном или экспоненциальном представлении, в зависимости от того, что больше подходит для данного значения и точности. %g печатает буквы нижнего регистра, а %G печатает прописные.
- %c — распечатать аргумент как один символ.
- %f — распечатать аргумент как число с плавающей запятой.
- %s — распечатать аргумент в виде строки.
- %% — вывести буквальный символ % .
Число без знака представляет ноль и положительные числа, а число со знаком представляет отрицательные, нулевые и положительные числа.
Следующая команда выводит число 100 в трех разных системах счисления:
Директива флагов
Флаги являются первыми необязательными модификаторами и используются для установки выравнивания, ведущих нулей, префиксов и т. Д.
Вот самые распространенные:
- — — Выровнять напечатанный текст в поле по левому краю. По умолчанию текст выравнивается по правому краю.
- + — Перед числами ставьте знаки + или — . По умолчанию только отрицательные числа имеют префикс со знаком минус.
- 0 — дополняет числа начальными нулями, а не пробелом.
- пустой — Перед положительными числами ставьте пробел, а отрицательные числа — минусом ( — ).
- # — Альтернативный формат чисел.
Директива по ширине
Поле директивы width помещается после любых символов флага и определяет минимальное количество символов, к которому должно привести преобразование.
Если ширина выводимого текста меньше указанной ширины, он заполняется пробелами. Ширина может быть указана как неотрицательное десятичное целое число или звездочка ( * ).
%20s означает, что длина поля должна быть не менее 20 символов. Перед текстом добавляются пробелы, поскольку по умолчанию вывод выравнивается по правому краю. Чтобы выровнять текст по левому %-20s , используйте флаг — ( %-20s ).
Когда звездочка ( * ) используется в качестве директивы width , тогда ширина поля преобразования устанавливается аргументом ширины, который предшествует аргументу, который форматируется.
В приведенном ниже примере мы устанавливаем ширину 10:
0 — это флаг, который дополняет число ведущими нулями вместо пробелов. Выходной текст будет содержать не менее 10 символов:
Директива о точности
Модификатор .precision состоит из точки ( . ), За которой следует положительное целое число или звездочка ( * ), которая в зависимости от типа спецификатора устанавливает количество строковых или цифровых символов или количество десятичных знаков, которые должны быть напечатаны.
Точность имеет следующий эффект:
- Если тип преобразования — целое число, точность определяет минимальное количество цифр, которые нужно напечатать. Если количество цифр в аргументе меньше точности, печатаются ведущие нули.
- Если тип преобразования — с плавающей запятой, точность определяет количество цифр, следующих за десятичным знаком. По умолчанию точность равна 6.
- Если тип преобразования — строка, точность определяет максимальное количество символов, которые нужно напечатать. Если количество символов в аргументе превышает точность, лишние символы усекаются.
Вот пример, показывающий, как округлить число с плавающей запятой до трех знаков после запятой:
Если для точности задана звездочка ( * ), ее значение устанавливается аргументом точности, который предшествует аргументу, который форматируется.
Выводы
Команда printf принимает формат и аргументы и печатает отформатированный текст.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Источник