Манипуляторы ввода -вывода
Кроме представленных ранее методов, существует и другой способ управления процессом ввода-вывода, основанный на использовании манипуляторов ввода-вывода. Манипуляторы позволяют менять режимы операций ввода-вывода непосредственно в выражениях внесения или извлечения. Для того чтобы использовать их в своей программе, в исходные тексты нужно включить заголовочный файл iomanip.h.
В прошлый раз мы накладывали ограничение на размер буфера cin, применяя метод width():
cin.width(sizeof(buff));
cin >> buff;
Теперь, используя манипулятор setw(), можно определить размер буфера так
cin >> setw (sizeof (buff)) >> buff;
Существует два вида манипуляторов ввода-вывода: параметризованные и непараметризованные. Вот список стандартных манипуляторов библиотеки iostream()
манипулятор | i/o | описание |
dec | o | устанавливает базу для преобразования чисел к 10-, |
oct | o | 8- |
hex | o | и 16-ичной форме |
ws | i | пропуск начальных пробелов |
ends | o | выводит нулевой символ |
endl | o | Выводит признак конца строки |
setfill (int ch) | o | Устанавливает символ-заполнитель |
setprecision(int n) | o | Устанавливает точность вывода чисел с плав точкой (знаков после запятой) |
setbase (int b) | o | устанавливает ширину поля для последующей операции |
setbase (int b) | o | устанавливает базу для преобразования числовых значений |
setiosflags (int f) | i/o | устанавливает отдельные флаги потока |
resetiosflags (int f) | i/o | сбрасывает отдельные флаги потока |
Вот некоторые из флагов потока
флаг | описание |
left | выравнивание по левому краю |
right | выравнивание по правому краю |
dec, oct, hex | устанавливают базу для ввода-вывода |
showbase | выводить показатель базы |
showpoint | выводить десятичную точку для чисел с плав точкой |
uppercase | 16-ричные большие буквы |
showpos | показать "+" для положительных целых чисел |
scientific | установить экспон форму для чисел с плав точкой |
fixed | установить формат чисел с фиксированной плав точкой |
Кроме того, вы можете создать свой собственные манипуляторы. Этому могут быть, по крайней мере, две причины. Во-первых, это может быть манипулятор, заключающий в себе некоторую часто встречающуюся в программе последовательность манипуляторов. Во-вторых, для управления нестандартными устройствами ввода-вывода.
Создание непараметризованных манипуляторов не очень сложное занятие. Все, что для этого нужно, это определить функцию, имеющую прототип, похожий на следующий:
ios& manipul (ios&);
Если вы пишите манипулятор только для вывода, ios замените на ostream, если для ввода - на istream.
В теле функции можно, что-то сделать с потоком, переданным в качестве параметров, а затем передать его в вызывающую программу на переданный функции аргумент типа поток.
Вот пример манипулятора для вывода с выравниванием по правому краю:
ostream & right(ostream &)
{
s << resetiosflags(ios::left) << setiosflags(ios::right);
return s;
}
Функция манипулятор изменяет биты флагов потока, переданного ей в качестве аргумента. После того, как right установит биты флагов потока, последний будет выводиться в таком режиме до тех пор, пока флаги потока не будут изменены.
Таким образом, выражение
cout << setw(20) << right<< 1234 << endl;
означает следующее. Манипулятор setw(20) установит поле вывода шириной 20 символов, манипулятор right установит выравнивание по правой границе поля вывода, выведется число, а манипулятор endl вызовет переход к следующей строке.
Параметризованные манипуляторы более сложны в написании, так как в этом случае необходимо создать класс, содержащий указатель на функцию - манипулятор и указатель на аргументы функции манипулятора. Макроопределения, которые облегчат процесс разработки параметризованных манипуляторов, содержатся в заголовочном файле iomanip.h.