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

* Сформулируйте достоинства и недостатки обоих подходов.

20.9. Состояние формата

Каждый объект класса из библиотеки iostream поддерживает состояние формата, которое управляет выполнением операций форматирования, например основание системы счисления для целых значений или точность для значений с плавающей точкой. Для модификации состояния формата объекта в распоряжении программиста имеется предопределенный набор манипуляторов.1 Манипулятор применяется к потоковому объекту так же, как к данным. Однако вместо чтения или записи данных манипулятор модифицирует внутреннее состояние потока. Например, по умолчанию объект типа bool, имеющий значение true (а также литеральная константа true), выводится как целая ‘1’:

#include iostream.h

int main()

{

bool illustrate = true;

cout "объект illustrate типа bool установлен в true: "

illustrate '\n';

}

Чтобы поток cout выводил переменную illustrate в виде слова true, мы применяем манипулятор boolalpha:

#include iostream.h

int main()

{

bool illustrate = true;

cout "объект illustrate типа bool установлен в true: ";

// изменяет состояние cout так, что булевские значения

// печатаются в виде строк true и false

cout boolalpha;

cout illustrate '\n';

}

Поскольку манипулятор возвращает потоковый объект, к которому он применялся, то допустимо прицеплять его к выводимым данным и другим манипуляторам. Вот как можно перемежать данные и манипуляторы в нашей программе:

#include iostream.h

int main()

{

bool illustrate = true;

cout "объект illustrate типа booclass="underline" "

illustrate

"\nс использованием boolalpha: "

boolalpha illustrate '\n';

// ...

}

Вывод данных и манипуляторов вперемежку может сбить пользователя с толку. Применение манипулятора изменяет не только представление следующего за ним объекта, но и внутреннее состояние потока. В нашем примере все значения типа bool в оставшейся части программы также будут выводиться в виде строк.

Чтобы отменить сделанную модификацию потока cout, необходимо использовать манипулятор noboolalpha:

cout boolalpha // устанавливает внутреннее состояние cout

illustrate

noboolalpha // сбрасывает внутреннее состояние cout

Как мы покажем, для многих манипуляторов имеются парные.

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

#include iostream

int main()

{

int ival = 16;

double dval = 16.0;

cout "ivaclass="underline" " ival

" установлен oct: " oct ival "\n";

cout "dvaclass="underline" " dval

" установлен hex: " hex dval "\n";

cout "ivaclass="underline" " ival

" установлен dec: " dec ival "\n";

}

Эта программа печатает следующее:

ivaclass="underline" 16 установлен oct: 20

dvaclass="underline" 16 установлен hex: 16

ivaclass="underline" 10 установлен dec: 16

* Но, глядя на значение, мы не можем понять, в какой системе счисления оно записано. Например, 20 – это действительно 20 или восьмеричное представление 16? Манипулятор showbase выводит основание системы счисления вместе со значением с помощью следующих соглашений: 0x в начале обозначает шестнадцатеричную систему (если мы хотим, чтобы вместо строчной буквы 'x' печаталась заглавная, то можем применить манипулятор uppercase, а для отмены – манипулятор nouppercase);

* 0 в начале обозначает восьмеричную систему;

* отсутствие того и другого обозначает десятичную систему.

Вот та же программа, но и с использованием showbase:

#include iostream

int main()

{

int ival = 16;

double dval = 16.0;

cout showbase;

cout "ivaclass="underline" " ival

" установлен oct: " oct ival "\n";

cout "dvaclass="underline" " dval

" установлен hex: " hex dval "\n";