
- •Классы потоков
- •Листинг 2. Форматирование с помощью манипуляторов
- •Листинг 3. Форматирующие флаги потоков
- •Состояние потока
- •Файловые потоки
- •Листинг 4. Примеры открытия файловых потоков
- •Бесформатный ввод-вывод
- •Класс istream
- •Класс ostream
- •Ввод-вывод с произвольным доступом
- •Листинг 5. Произвольный доступ к файлу
- •Заключение
Листинг 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). Мы поедпочитаем первый способ.