Выбрать главу

 showflags(f);

 return 0;

}

void showflags(ios::fmtflags f)

{

 long i;

 for(i=0x4000; i; i=i>>1)

  if(i & f) cout << "1";

  else cout << "0";

 cout << "\n";

}

При выполнении эта программа отображает такие результаты. (Между этими и вашими результатами возможно расхождение, вызванное использованием различных компиляторов.)

0 0 0 0 0 1 0 0 0 0 0 0 0 0 1

0 0 1 0 0 1 0 0 0 1 0 0 0 0 1

0 0 0 0 0 1 0 0 0 1 0 0 0 0 1

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

Установка ширины поля, точности и символов заполнения

Помимо флагов форматирования можно также устанавливать ширину поля, символ заполнения и количество цифр после десятичной точки (точность). Для этого достаточно использовать следующие функции.

streamsize width(streamsize len);

char fill(char ch);

streamsize precision(streamsize num);

Функция width() возвращает текущую ширину поля и устанавливает новую равной значению параметра len. Ширина поля, которая устанавливается по умолчанию, определяется количеством символов, необходимых для хранения данных в каждом конкретном случае. Функция fill() возвращает текущий символ заполнения (по умолчанию используется пробел) и устанавливает в качестве нового текущего символа заполнения значение, заданное параметром ch. Этот символ используется для дополнения результата символами, недостающими для достижения заданной ширины поля. Функция precision() возвращает текущее количество цифр, отображаемых после десятичной точки, и устанавливает новое текущее значение точности равным содержимому параметра num. (По умолчанию после десятичной точки отображается шесть цифр.) Тип streamsize определен как целочисленный тип.

Рассмотрим программу, которая демонстрирует использование этих трех функций.

#include <iostream>

using namespace std;

int main()

{

 cout.setf(ios::showpos);

 cout.setf(ios::scientific);

 cout << 123 << " " << 123.23 << "\n";

 cout.precision(2); // Две цифры после десятичной точки.

 cout.width(10); // Всё поле состоит из 10 символов.

 cout << 123 << " ";

 cout.width(10); // Установка ширины поля равной 10.

 cout << 123.23 << "\n";

 cout.fill('#'); // Для заполнителя возьмем символ "#"

 cout.width(10); // и установим ширину поля равной 10.

 cout << 123 << " ";

 cout.width(10); // Установка ширины поля равной 10.

 cout << 123.23;

 return 0;

}

Эта программа генерирует такие результаты.

+123 +1.232300е+002

       +123 +1.23е+002

######+123 +1.23е+002

В некоторых реализациях необходимо устанавливать значение ширины поля перед выполнением каждой операции вывода. Поэтому функция width() в предыдущей программе вызывалась несколько раз.

В системе ввода-вывода C++ определены и перегруженные версии функций width(), precision() и fill(), которые не изменяют текущие значения соответствующих параметров форматирования и используются только для их получения. Вот как выглядят их прототипы,

char fill();

streamsize width();

streamsize precision();

Использование манипуляторов ввода-вывода

Манипуляторы позволяют встраивать инструкции форматирования в выражение ввода-вывода.

В С++-системе ввода-вывода предусмотрен и второй способ изменения параметров форматирования, связанных с потоком. Он реализуется с помощью специальных функций, называемых манипуляторами, которые можно включать в выражение ввода-вывода. Стандартные манипуляторы описаны в табл. 18.1.