Урок 6.2. Форматный вывод
6.2. Форматный вывод
Форматный ввод-вывод позволяет передавать программе и выдавать из программы на внешнее устройство символьные, строковые и числовые значения, обеспечивая преобразование данных в процессе ввода-вывода. Для форматного вывода используется функция printf(), обращение к которой, в общем виде можно записать следующим образом:
printf(<строка_вывода>,<список_вывода>); |
где
- <строка_вывода> – это строка, в состав которой входят обычные символы и группы специальных символов, называемых форматами (или спецификациями преобразований);
- <список_вывода> – это перечисление элементов вывода, отделенных друг от друга запятой: <элемент1>,<элемент2>,...,<элементN>. В качестве <элемент> могут быть использованы константы, переменные и выражения.
Строка вывода и список вывода, в свою очередь, должны быть отделены друг от друга запятой, как это видно из общей формы записи функции printf(). Функция printf() печатает строку вывода и значения элементов списка вывода. Если в качестве элемента записана константа, то печатается константа; если переменная, то печатается значение переменной; если выражение, то печатается значение выражения. Чтобы разобраться, как работает функция printf() и какова роль форматов в строке вывода, рассмотрим фрагмент программы:
int x,y; x=8;y=5; printf("Если к %d прибавить %d, то получим %d.",x,y,x+y); |
Что будет напечатано в результате выполнения программы? Во-первых, "разложим" обращение к функции на составные части в соответствии с общей формой записи. Строка:
"Если к %d прибавить %d, то получим %d.",
названная в наших обозначениях строкой вывода, содержит, кроме обычных символов, 3 группы символов, представляющих собой форматы, а именно: %d %d %d , которые обозначают, что в списке вывода имеются 3 элемента, значения которых должны быть напечатаны в форме десятичной целой константы (об этом говорит символ в форматах – d). Во-вторых, список вывода содержит 3 элемента, значения которых нужно напечатать: две переменные и одно выражение: x,y,х+у.
Таким образом, каждому формату из строки вывода соответствует элемент из списка вывода. Функция printf() осуществляет печать строки вывода, и если в ней имеется формат, то вместо i-ого формата "вставляется" в печатаемую строку значение i-ого элемента списка вывода. В результате выполнения этого фрагмента программы будет напечатано:
Если к 8 прибавить 5, то получим 13.
В общем случае форматы определяют, к какому виду должны быть преобразованы значения печатаемых элементов, и поэтому форматы часто называют еще и по-другому – спецификациями преобразования.
Так, например, значение элемента типа int может быть напечатано в виде вещественной константы с точкой или с порядком, либо в виде шестнадцатеричного или восьмеричного представления.
Каким же образом компилятор выделяет форматы из строки вывода? Отличительным признаком формата является символ %, за которым следуют строго определенные символы, задающие формат. В общем случае формат, содержащийся в строке вывода, имеет следующую форму записи:
%-<строка цифр1>.<строка цифр2 l символ преобразования> |
Обязательными составными частями формата должны быть первый символ % и последний символ <символ преобразования>. Остальные компоненты общей формы записи могут быть опущены, как это имеет место в только что рассмотренном примере (формат %d, где d – cимвол преобразования).
Символ преобразования определяет, в каком виде должно быть напечатано выводимое значение. В качестве символа преобразования могут быть использованы символы из таблицы 6.1.
Таблица 6.1. Символы преобразования
Символ преобразо- вания | Вид печатаемого значения |
d, i | Десятичная целая константа |
c | Одиночный символ |
s, S | Строка символов |
e, E | Вещественная константа с порядком |
f, F | Вещественная константа с точкой |
a, A | Вещественная константа в шестнадцатеричном виде |
u | Десятичная целая константа без знака |
o | Восьмеричная целая константа без знака |
х, X | Шестнадцатеричная целая константа без знака |
g, G | Используется вместо f и е, для сокращения записи |
p | Указатель |
n | Указатель на int |
Замечание. n – спецификатор указывающий, что в целочисленной переменной, на которую указывает ассоциированный с данным спецификатором указатель, будет храниться число символов, выведенных к моменту обработки спецификации %n, ничего печататься при этом не будет. Пример смотрите в конце страницы.
Составные части формата, находящиеся между символом % и символом преобразования, называются модификаторами. Влияние модификаторов, если они использованы в формате, на вид печатаемого значения заключается в следующем:
- знак минус указывает на то, что печатаемое значение должно быть "прижато" к левой границе поля вывода. Если минус в формате отсутствует, печатаемое значение прижимается к правой границе поля вывода;
- <строка цифр1> задает минимальную ширину (размер) поля вывода. Большее поле будет использовано, если печатаемое число (или строка) не помещается в заданное поле. Если печатаемое число (или строка) меньше заданной ширины поля вывода, то оно дополняется ведущими пробелами так, чтобы была выдержана заданная ширина поля. Если <строка цифр1> начинается с нуля (этот нуль не означает, что размер восьмеричный), то вместо пробелов добавляются нули;
- знак точка отделяет <строку цифр1> от <строки цифр2>;
- <строка цифр2> определяет разрядность. Для вещественных типов данных – количество печатаемых цифр справа от десятичной точки, для строк – количество печатаемых символов;
- l – маркер длины указывает, что соответствующий элемент данных имеет тип long, а не int.
Рассмотрим, как форматы влияют на вид печатаемых значений.
Пример1. Влияние модификатора ширины поля <строка цифр1> на печать целого числа.
main() { printf("//%d//\n",336); //модификаторы отсутствуют printf("//%2d//\n",336); //ширина поля меньше ширины числа printf("//%10d//\n",336); //ширина поля больше ширины числа printf("//%-10d//\n",336); //число прижато к левой границе поля вывода } |
В строке вывода записаны символы /, чтобы при печати было видно, где начинается и заканчивается каждое поле. Кроме того, в строке вывода имеется управляющий символ \n (новая строка), который обеспечивает для каждой функции printf() печать с новой строки. Результат выполнения программы будет следующим:
/336/ /336/ / 336/ /336 /
Пример 2. Влияние форматов на печать вещественных данных.
main() { printf("//%f//\n",1234.56); //модификаторов нет printf("//%e//\n",1234.56); //модификаторов нет printf("//%4.2f//\n",1234.56); //число не входит в заданную ширину printf("//%3.1f//\n",1234.56); //число не входит в ширину printf("//%10.3f//\n",1234.56); printf("//%10.3e//\n",1234.56); } |
Результаты выполнения:
/1234.560000/
/1.234560е+03/
/1234.56/
/1234.6/
/ 1234.560/
/ 1.234е+03/
В первых двух случаях модификаторы отсутствуют. С шириной поля все ясно – число занимает такой размер поля, который ему требуется, а вот точность по умолчанию равна 6, что обозначает 6 знаков после десятичной точки. Как видим, напечатанное число в формате %f отличается от исходного. Это произошло потому, что на печать выводится 10 цифр, в то время как числа с плавающей точкой в системе, на которой была просчитана программа, изображаются с точностью до 6-7 цифр.
По умолчанию для формата %е в мантиссе печатается одна цифра слева от десятичной точки и шесть справа, а порядок подбирается такой, чтобы обеспечить необходимое значение. Однако лишние нули нет смысла выводить и, чтобы избежать этого, нужно задать точность – число цифр справа от десятичной точки. Последние четыре оператора записаны с модификаторами ширины поля точности. Обратите внимание, что четвертый и шестой операторы производят округление выводимых данных.
Пример 3. Влияние модификаторов на печать строк.
main() { printf("//%2s//\n","Выдающееся достижение!"); printf("//%25s//\n","Выдающееся достижение!"); printf("//%25.5s//\n","Выдающееся достижение!"); printf("//%-25.5s//\n","Выдающееся достижение!"); } //Результат работы программы: /Выдающееся достижение!/ / Выдающееся достижение!/ / Выдаю/ /Выдаю / |
В заключение отметим некоторые особенности использования функции printf() для вывода результатов работы программы.
1. Функция printf() использует строку вывода, для того чтобы определить, сколько будет элементов в списке вывода. Таким образом, i-ому формату строки вывода должен соответствовать i-ый элемент списка вывода. Программа будет выдавать абсурдные результаты, если количество форматов и количество элементов вывода не будет совпадать.
2. Функцию printf() можно использовать для печати каких-либо сообщений. В этом случае в строке вывода не должно быть форматов, а список вывода должен отсутствовать, например: printf("данные:\n");
3. Если в строке вывода имеются управляющие символы (см. 3.1.3.), то они действуют в соответствии с функциональным назначением, осуществляя, например, подачу звукового сигнала, возврат каретки, переход на новую строку и т.д.
4. В случае возникновения ошибки вывода функция возвращает EOF, в противном случае возвращается количество выведенных символов и, следовательно, допустим оператор программы, например, такой: к=printf("%d\n",j);
5. Так как символ % является признаком формата, то для того, чтобы его напечатать, в строке вывода нужно задать \% или %%, например:
int k=25; printf("Ожидается снижение цен на %d\%",k); |
В результате отработки этого фрагмента программы будет напечатано:
Ожидается снижение цен на 25%
Как факт маловероятно, но именно это будет напечатано.
6.Для записи количества выведенных символов на данный момент используется формат n
main() { int i = 0; int *ptri = &i; printf("12345678%n abc",ptri); //по адресу ptri запишется количество //выведенных символов на момент printf("\ni = %d",i); //использования формата %n getch(); } // результат работы программы 12345678 abc i = 8 |
Оставить комментарий