В третьей строке показано, что использование спецификатора точности (%5.3d) с целочисленной формой дополняет число ведущими нулями до получения минимального количества цифр (трех в данном случае). Однако применение флага 0 приводит к дополнению представления числа ведущими нулями, которых достаточно для заполнения всей ширины поля. Наконец, при одновременном указании флага 0 и спецификатора точности флаг 0 игнорируется.
Теперь исследуем некоторые варианты со строкой. Рассмотрим программу в листинге 4.10.
Листинг 4.10. Программа stringf. с


Обратите внимание, что спецификатор %2s расширяет поле настолько, чтобы уместить все символы строки. Кроме того, спецификатор точности ограничивает количество выводимых символов. Конструкция . 5 в спецификаторе формата сообщает функции printf() о том, что нужно вывести только пять символов. Опять-таки, модификатор - выравнивает текст по левому краю.
Использование полученных знаний на практике
Итак, вы ознакомились с несколькими примерами. Как должен выглядеть оператор для вывода текста в следующей форме:
Семья NAME может стать богаче на $ХХХ.ХХ!
138 Глава 4
Здесь NAME и XXX. XX представляют значения, которые будут предоставляться в программе переменными, скажем, name [40] и cash.
Одно из возможных решений выглядит гак:
printf("Семья %s может стать богаче на $%.2f!\n", name, cash);
Что поеобоазует спецификатоо поеобоазования?
Теперь более подробно рассмотрим, что именно преобразует спецификатор преобразования. Он преобразует значение, хранящееся в памяти компьютера в двоичном формате, в последовательность символов (строку) с целью отображения. Например, число 76 может быть представлено в памяти компьютера в двоичном виде как 01001100. Спецификатор преобразования %d превращает его в символы 7 и 6, отображая 76. Преобразование %х превращает это же двоичное значение (01001100) в шестнадцатеричное представление 4с, а спецификатор %с преобразует его в символьное представление L.
Термин преобразование, возможно, в чем-то неточен, т.к. можно предположить, что исходное значение заменяется преобразованным. Спецификаторы преобразования по существу являются спецификаторами трансляции; к примеру, %d означает “транслировать заданное значение в десятичное целочисленное текстовое представление и затем вывести его”.
Несовпадающие преобразования
Естественно, спецификатор преобразования должен соответствовать типу выводимого значения. Часто вам доступно несколько вариантов. Например, для вывода значения типа int можно применять спецификатор %d, %х или %o. Все эти спецификаторы предполагают, что вы выводите значение типа int; они просто предоставляют различные представления этого значения. Аналогично, спецификаторы %f, %е или %д можно использовать для представления типа double.
Что произойдет, если спецификатор преобразования не соответствует типу? В предыдущей главе вы уже видели, что несоответствия могут вызвать проблемы. Это очень важный аспект, который следует иметь в виду, так что в листинге 4.11 приведено еще несколько примеров несоответствия при работе с семейством целочисленных типов.
Листинг 4.11. Программа intconv.c

Символьные строки и форматированный ввод-вывод 139
В нашей системе были получены следующие результаты:
num как тип short и тип unsigned short: 336 336 -num как тип short и тип unsigned short: -336 65200 num как тип int и тип char: 336 Р WORDS тип int, short и char: 65618 82 R
Взглянув на первую строку, вы можете заметить, что спецификаторы %hd и %hu выдают 336 в качестве вывода для переменной num; туг нет никаких проблем. Однако во второй строке версия %u (без знака) для mnum выглядит как 65200, а не как ожидаемое значение 336; это вытекает из способа представления значений типа short int со знаком в нашей системе. Во-первых, они имеют размер 2 байта. Во-вторых, для представления целых чисел со знаком система использует метод, называемый поразрядным дополнением до двойки. При таком методе числа от 0 до 32767 представляют сами себя, а числа от 32768 до 65535 представляют отрицательные числа, причем 65535 соответствует -1, 65534 2 и т.д. Следовательно, -336 представлено как 65536 - 336, или
65200. Таким образом, число 65200 представляет -336, когда интерпретируется как int со знаком, и 65200, когда интерпретируется как int без знака. Поэтому будьте осторожны! Одно число может интерпретироваться как два разных значения. Описанный метод представления отрицательных целых чисел применяется не во всех системах. Тем не менее, мораль этого примера: не рассчитывайте на то, что преобразование %u просто отбросит знак числа.
Читать дальше