Манипуляторы
Манипуляторы потоков являются по существу функциями, которые можно вызывать непосредственно в цепочке операций извлечения или передачи в поток. Различают простые и параметризованные манипуляторы. У простых манипуляторов аргументы отсутствуют. Параметризованные манипуляторы имеют аргумент.
Ниже приводится сводка имеющихся манипуляторов, как простых, так и параметризованных. Они Перечислены в алфавитном порядке.
Таблица 9.2. Простые и параметризованные манипуляторы
Манипулятор | Описание | ||
dec | Задает десятичную базу преобразования. | ||
end1 | Передает в поток символ новой строки и сбрасывает поток. | ||
ends | Передает в поток символ завершающего строку нуля. |
| |
flush | Сбрасывает выходной поток. | ||
hex | Задает шестнадцатеричную базу преобразования. | ||
lock(ios Sir) | Блокирует дескриптор файла потока ir. | ||
oct | Задает восьмеричную базу преобразования. | ||
resetiosflags(int f) | Сбрасывает флаги, биты которых установлены в f. | ||
setbase(int b) | Устанавливает базу преобразования (0, 8, 10 или 16). | ||
setiosflags(int f) | Устанавливает флаги, биты которых установлены в f. | ||
setfill(int c) | Задает символ заполнения (аналогичен функции
fiilO). | ||
setprecision(long p) | Задает точность (аналогичен функции precision ()). | ||
setw(iong w) | Задает ширину поля (аналогичен функции width ()). | ||
lunlock(ios &ir) | Разблокирует дескриптор файла для потока ir. | ||
ws | Исключает начальные пробельные символы. |
Вот пример использования некоторых манипуляторов (мы создали один свой собственный):
Листинг 9.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;
}
Рис. 9.1 Манипулятор, выводящий свой аргумент в двоичной форме