Операции вставки класса ostream преобразуют значения в текстовый вид. По умолчанию они форматируют значения следующим образом:
Значение типа char, если оно представляет собой символ, который можно вывести, печатается как символ в поле, размер которого составляет один символ.
Числовые значения целого типа выводятся как десятичные целые числа в поле, размер которого достаточен для вывода всех цифр и при необходимости для вывода знака минус.
Строки выводятся в поле, размер которого равен длине строки.
Типы чисел с плавающей точкой выводятся в шести полях, замыкающие нули не выводятся. (Важно, что количество выводимых цифр никак не связано с точностью, с которой число хранится в памяти.) Число выводится в записи с фиксированной десятичной точкой или в научной записи — в зависимости от величины числа. В частности, научная запись используется в том случае, если показатель имеет значение 6 и больше или -5 и меньше. Снова поле является достаточно большим, чтобы поместить число и при необходимости знак минус. Поведение, заданное по умолчанию, отвечает использованию функции fprintf() стандартной библиотеки С со спецификатором %g.
Поскольку каждое значение выводится в поле, размер которого соответствует этому значению, необходимо явно указывать пробелы между значениями, иначе последовательные значения сольются вместе.
Изменение системы счисления при выводе
Класс ostream наследуется из класса ios, который, в свою очередь, наследуется из класса ios_base. В классе ios_base сохраняется информация, необходимая для форматирования вывода. Например, определенные биты в одном из элементов класса показывают, какая система счисления используется для вывода, а другой элемент класса определяет ширину поля. Используя манипуляторы, можно управлять системой счисления при выводе целых чисел. С помощью функций-элементов класса ios_base можно контролировать ширину и количество полей, отводимых для отображения цифр, находящихся справа от десятичной точки. Поскольку класс ios_base является косвенным базовым классом для класса ostream, можно использовать его методы вместе с такими объектами класса ostream (или его потомков), как cout.
Посмотрим, например, как установить систему счисления для вывода целых чисел. Чтобы вывести целые числа в десятичной, шестнадцатиричной или восьмеричной системе счисления, можно воспользоваться манипуляторами dec, hex или oct. Например, при вызове функции hex(cout) устанавливается шестнадцатиричная система счисления для форматирования в объекте cout. После однократного вызова программа будет выводить числа в шестнадцатиричной форме до тех пор, пока состояние форматирования не будет изменено.
Несмотря на то что манипуляторы реально являются функциями, их обычно используют следующим образом: cout « hex.
Класс ostream перегружает операцию « так, чтобы ее использование было эквивалентно вызову функции hex(cout).
Установка ширины полей.Можно воспользоваться функцией-элементом width, чтобы поместить различные числа в поля одинаковой ширины. Метод имеет следующие прототипы:
int width();
int width(int i);
Первая форма возвращает текущую установку для ширины полей. Вторая устанавливает ширину поля равной i пробелам и возвращает предыдущее значение ширины поля. Это позволяет сохранить предыдущее значение в том случае, если оно может понадобиться в будущем.
Метод width() влияет только на следующий вывод, а после него ширина поля возвращается к предыдущему значению. Например, рассмотрим следующее выражение:
cout « ‘#’ ;
cout.width(12);
cout « 12 « # « 24 « #n;
Выражение отображает на экране следующую информацию:
# 12#24#
Число 12 выводится в поле из 12 символов, выровненное по правой стороне. Это называется выравниванием справа. После этого ширина поля возвращается к значению, заданному по умолчанию, и два символа # и число 24 выводятся в полях необходимого для них размера.
Язык C++ никогда не урезает отображаемые данные, поэтому, если попытаться вывести на печать значение из семи символов в поле из двух символов, C++ расширит поле, чтобы вместить данные.
Символы – заполнители.По умолчанию cout заполняет поля пробелами. Для изменения символа-заполнителя можно использовать метод fill(). Например, в результате вызова метода cout.fill(‘*’) символ-заполнитель заменяется на звездочку. Это может быть удобно, например, для печати чеков, чтобы получатель не мог добавить несколько цифр к числу. в отличие от ширины полей, новый символ заполнения будет действовать до тех пор, пока его не изменить явно.
Установка точности при выводе чисел с плавающей точкой.Значение точности чисел с плавающей точкой зависит от режима вывода. В режиме, заданном по умолчанию, она обозначает количество выводимых цифр. В фиксированном или научном режиме, точность обозначает количество цифр выводимых после десятичной точки. Точность, установленная для C++ по умолчанию, равна 6 (замыкающие нули отбрасываются). Функция-элемент precision() позволяет выбрать другие значения. Например, выражение cout.precision(2) заставляет объект cout использовать точность, равную 2. В отличие от случая с функцией width(), но подобно случаю с функцией fill(), новые установки точности остаются действовать до их явного обновления.
Вывод замыкающих нулей и десятичной точки.Некоторые формы вывода, например цены или цифры в колонках, выглядят лучше, если замыкающие нули присутствуют. Семейство классов iostream не включает функцию, которая могла бы выполнить эту задачу. Однако класс ios_base содержит функцию setf() (сокращение от слов set flag — установить флаг), которая управляет определенными свойствами форматирования. Класс также определяет несколько констант, которые можно использовать в качестве аргументов этой функции. Например, вызов функции cout.setf(ios_base::showpoint) заставляет cout вывести десятичную точку.
showpoint — это статическая константа в диапазоне доступа класса ios_base, определенная в объявлении класса. Диапазон доступа класса указывает, что нужно использовать оператор диапазона доступа (::) с именем константы, если это имя применяется за пределами метода класса. Таким образом, ios_base::showpoint — это имя константы, определенной в классе ios_base.
Стандартные манипуляторы.Использование setf() — это не самый удобный для пользователя подход к форматированию, поэтому C++ имеет несколько манипуляторов, которые вызывают setf(), автоматически задавая необходимые аргументы. Эти манипуляторы работают так же, как hex. Например, оператор cout « left « fixed задает выравнивание слева и запись с десятичной точкой. В табл. 16.3 перечислены различные манипуляторы.
Таблица 1. Некоторые стандартные манипуляторы.
C++. Форматированный ввод и вывод