Но большинство программ (и что еще важней, разработчиков) ожидают, что состояние потока будет соответствовать стандартным библиотечным значениям. В этих случаях оставленный в нестандартном состоянии поток может привести к ошибке. В результате обычно лучше отменить изменение состояния, как только оно больше не нужно.
Хорошим примером манипулятора, изменяющего состояние формата своего объекта, является манипулятор boolalpha
. По умолчанию значение типа bool
выводится как 1
или 0
. Значение true
выводится как целое число 1
, а значение false
как 0
. Это поведение можно переопределить, применив к потоку манипулятор boolalpha
:
cout << "default bool values: " << true << " " << false
<< "\nalpha bool values: " << boolalpha
<< true << " " << false << endl;
Эта программа выводит следующее:
default bool values: 1 0
alpha bool values: true false
Как только манипулятор boolalpha
"записан" в поток cout
, способ вывода логических значений изменяется. Последующие операции вывода логических значений отобразят их как "true"
или "false"
.
Чтобы отменить изменение флага формата потока cout
, применяется манипулятор noboolalpha
:
bool bool_val = get_status();
cout << boolalpha //
<< bool_val
<< noboolalpha; //
Здесь формат вывода логических значений изменен только для вывода значения bool_val
. Как только это значение будет выведено, поток немедленно возвращается в первоначальное состояние.
По умолчанию целочисленные значения выводятся и читаются в десятичном формате. Используя манипуляторы hex
, oct
и dec
, базу записи числа можно изменить на восьмеричную, шестнадцатеричную и обратно на десятичную базу:
cout << "default: " << 20 << " " << 1024 << endl;
cout << "octal: " << oct << 20 << " " << 1024 << endl;
cout << "hex: " << hex << 20 << " " << 1024 << endl;
cout << "decimal: " << dec << 20 << " " << 1024 << endl;
После компиляции и запуска на выполнение эта программа выводит следующее:
default: 20 1024
octal: 24 2000
hex: 14 400
decimal: 20 1024
Обратите внимание, как и манипулятор boolalpha
, эти манипуляторы изменяют флаг формата. Они срабатывают сразу после применения и влияют на весь последующий вывод целочисленных значений, пока формат не изменит применение другого манипулятора.
hex
, oct
и dec
влияют на вывод только целочисленных операндов, но не значений с плавающей запятой.
По умолчанию при выводе числа нет никакого визуального уведомления об используемой базе. Например, 20 — это действительно 20, или восьмеричное представление числа 16? Когда числа выводятся в десятичном режиме, они отображаются, как и ожидается. Если необходимо выводить восьмеричные или шестнадцатеричные значения, вероятней всего, придется использовать также манипулятор showbase
. Он заставляет поток вывода использовать те же соглашения, что и при определении базы целочисленных констант.
• Предваряющий 0x
означает шестнадцатеричный формат.
• Предваряющий 0
означает восьмеричный формат.
• Отсутствие любого индикатора означает десятичное число.
Здесь предыдущая программа пересмотрена для использования манипулятора showbase
:
cout << showbase; //
cout << "default: " << 20 << " " << 1024 << endl;
cout << "in octal: " << oct << 20 << " " << 1024 << endl;
cout << "in hex: " << hex << 20 << " " << 1024 << endl;
cout << "in decimal: " << dec << 20 << " " << 1024 << endl;
cout << noshowbase; //
Вывод пересмотренной программы проясняет смысл:
default: 20 1024
in octal: 024 02000
in hex: 0x14 0x400
in decimal: 20 1024
Манипулятор noshowbase
возвращает поток cout
в прежнее состояние, когда индикатор базы не отображается.