Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Потоки ввода-вывода.doc
Скачиваний:
0
Добавлен:
14.11.2019
Размер:
338.94 Кб
Скачать

Листинг 2. Форматирование с помощью манипуляторов

/////////////////////////////////////////////////

// Manip.cpp: Демонстрация некоторых манипуляторов.

//

#include <iomanip.h>

#pragma hdrstop

#include <condefs.h>

//////////////////////////////////////////////////

// Манипулятор, определенный пользователем - звонок.

//

ostream shell(ostream &os)

{

return os<< '\a';

#pragma argsused

int main(int argc, char* argv[])

{

cout “ bell; // Тестирование манипулятора bell.

//

// Манипуляторы базы преобразования.

//

long 1 = 123456;

cout<< "Hex: "<< hex<< 1<< end1

<<"Oct: "<< oct<< 1<< end1

<< "Dec: " << dec << 1 << end1;

//

// Параметризованные манипуляторы.

//

int h=12, m=5, s=0; // To же, что в примере

// Format.cpp. cout << "The time is " << setfill('0')

<< setw(2) << h << ':'

<< setw(2) << m << ':'

<< setw(2) << s << setfillC ') << end1;

return 0;

}

Как видите, очень несложно определить свой собственный простой манипулятор. Это всего лишь функция, возвращающая ссылку на переданный ей в параметре поток.

Примечание

Создать параметризованный манипулятор не так просто. Существуют различные способы сделать это, но наиболее очевидный из них — реализация манипулятора через класс эффектора. Идея состоит вот в чем. Нужно определить для манипулятора собственный класс с конструктором, принимающим нужные параметры, •и перегрузить для этого класса операцию передачи (извлечения) соответствующего потока. После этого конструктор можно вызывать в качестве параметризованного манипулятора. Создается временный объект, который выводится в поток перегруженной операцией и удаляется. Ниже показан манипулятор, который выводит в поток свой аргумент типа unsigned в двоичной форме.

#include <iostream.h>

// Класс эффектора.

class Bin {

int val;

public:

Bin(unsigned arg) { val = arg; }

friend ostream &operator“(ostreams. Bin);

};

// Вывод числа в двоичной форме.

ostream &ooerator<<(ostream &os. Bin b) {

int cb = 1; // Контрольный бит для отсчета циклов.

do {

if (b.val <0) // Если val < 0, то старший бит = 1. os << 1;

else

os<< 0;

} while (b.vai<<= 1, cb<<= 1) ;

return os;

}

int main ()

(

unsigned n = Ox00ff0f34;

cout<< "Some binary: "<< Bin(n)<< end1;

return 0;

}

Рис. 1 Манипулятор, выводящий свой аргумент в двоичной форме

Форматирующие флаги

Флаги управления форматированием являются битовыми полями, хранящимися в переменной типа fmtflags (псевдоним int). Для их чтения и/или модификации могут применяться следующие функции-элементы класса ics:

  • int flags (), int flags (int). Без параметра возвращает текущее состояние флагов. При указанном параметре устанавливает новые значения флагов и возвращает их прежнее состояние.

  • int setf(int), long setf(int, int). Первая форма устанавливает флаги, биты которых установлены в параметре. Вторая форма модифицирует флаги, биты которых установлены во втором параметре. Значения этих флагов задаются первым параметром. Возвращает прежнее состояние всех флагов.

  • void unsetf(int). Сбрасывает флаги, биты которых установлены в параметре.

Помимо функций, для управления флагами можно пользоваться манипуляторами setiosflags (аналог setf() с одним параметром) и reset-iosflags (аналог unsetf ()).

В таблице 3 описаны форматирующие флаги потоков.

Таблица 3. Форматирующие флаги класса ios

Флаг

Описание

internal

Если установлен, при выводе чисел знак выводится на левом краю поля вывода, а само число выравнивается по правому краю поля. Промежуток заполняется текущим символом заполнения.

dec

Устанавливает десятичное представление чисел. Принимается по умолчанию.

oct

Устанавливает восьмеричное представление чисел.

hex

Устанавливает шестнадцатеричное представление чисел.

showbase

Если установлен, то при восьмеричном и шестнадцатеричном представлении чисел выводит индикатор основания (0 для восьмеричных и Ох для шестнадцатеричных чисел).

showpoint

Если установлен, для вещественных чисел всегда выводится десятичная точка.

uppercase

Если установлен, шестнадцатеричные цифры от А до F, а также символ экспоненты Е выводятся в верхнем регистре.

boolalpfa

Если установлен, булевы значения выводятся как слова “true/false”. В противном случае они представляются соответственно единицей и нулем.

showpos

Выводит + для положительных чисел.

scientific

Если установлен, вещественные числа выводятся в научной (экспоненциальной) нотации.

fixed

Если установлен, вещественные числа выводятся в десятичном формате (с фиксированной точкой).

unitbuf

Если установлен, поток сбрасывается после каждой операции передачи.

 Несколько замечаний относительно перечисленных в таблице флагов.

  • Флаги left, right и internal являются взаимоисключающими. В данный момент времени может быть установлен только один из них.

  • Взаимоисключающими являются также флаги dec, oct и hex.

  • При модификации базы представления в качестве второго параметра setf() можно использовать константу ios: :basefield.

  • При модификации выравнивания в поле можно аналогичным образом использовать константу ios: :adjustfield.

  • При модификации формы представления (нотации) чисел с плавающей точкой можно использовать константу ios : : floatfield. Ниже мы приводим листинг программы, демонстрирующей применение различных флагов форматирования.

Примечание

Имена перечисленных выше флагов и других констант принадлежат к области действия класса ios. Вне этого класса нужно либо воспользоваться разрешением области действия (ios : : scientific), либо обращаться к ним, как к элементам существующего объекта (cout. scientific). Мы поедпочитаем первый способ.