В классе ios содержится состояние формата, которое управляется
функциями flags() и setf(). По сути эти функции нужны, чтобы
установить или отменить следующие флаги:
class ios {
public:
// управляющие форматом флаги:
enum {
skipws=01, // пропуск обобщенных пробелов для input
// поле выравнивания:
left=02, // добавление перед значением
right=04, // добавление после значения
internal=010, // добавление между знаком и значением
// основание целого:
dec=020, // восьмеричное
oct=040, // десятичное
hex=0100, // шестнадцатеричное
showbase=0200, // показать основание целого
showpoint=0400, // выдать нули в конце
uppercase=01000, // 'E', 'X' , а не 'e', 'x'
showpos=02000, // '+' для положительных чисел
// запись числа типа float:
scientific=04000, // .dddddd Edd
fixed=010000, // dddd.dd
// сброс в выходной поток:
unitbuf=020000, // после каждой операции
stdio=040000 // после каждого символа
};
//...
};
Смысл флагов будет разъяснен в последующих разделах. Конкретные
значения флагов зависят от реализации и даны здесь только для того,
чтобы избежать синтаксически неверных конструкций.
Определение интерфейса как набора флагов и операций для их
установки или отмены - это оцененный временем, хотя и несколько
устаревший прием. Основное его достоинство в том, что пользователь
может собрать воедино набор флагов, например, так:
const int my_io_options =
ios::left|ios::oct|ios::showpoint|ios::fixed;
Такое множество флагов можно задавать как параметр одной операции
cout.flags(my_io_options);
а также просто передавать между функциями одной программы:
void your_function(int ios_options);
void my_function()
{
// ...
your_function(my_io_options);
// ...
}
Множество флагов можно установить с помощью функции flags(), например:
void your_function(int ios_options)
{
int old_options = cout.flags(ios_options);
// ...
cout.flags(old_options); // reset options
}
Функция flags() возвращает старое значение множества флагов. Это
позволяет переустановить значения всех флагов, как показано выше,
а также задать значение отдельному флагу. Например вызов
myostream.flags(myostream.flags()|ios::showpos);
заставляет класс myostream выдавать положительные числа со знаком
+ и, в то же время, не меняет значения других флагов. Получается
старое значение множества флагов, к которому добавляется с помощью
операции | флаг showpos. Функция setf() делает то же самое,
поэтому эквивалентная запись имеет вид
myostream.setf(ios::showpos);
После установки флаг сохраняет значение до явной отмены.
Все-таки управление вводом-выводом с помощью установки и отмены
флагов - грубое и ведущее к ошибкам решение. Если только вы тщательно
не изучите свое справочное руководство и не будете применять флаги
только в простых случаях, как это делается в последующих разделах, то
лучше использовать манипуляторы (описанные в 10.4.2.1). Приемы работы
с состоянием потока лучше изучить на примере реализации класса, чем
изучая интерфейс класса.
10.4.1.4 Вывод целых
Прием задания нового значения множества флагов с помощью операции | и
функций flags() и setf() работает только тогда, когда один бит определяет
значение флага. Не такая ситуация при задании системы счисления целых
или вида выдачи вещественных. Здесь значение, определяющее вид выдачи,
нельзя задать одним битом или комбинацией отдельных битов.
Решение, принятое в , сводится к использованию
версии функции setf(), работающей со вторым "псевдопараметром", который
показывает какой именно флаг мы хотим добавить к новому значению.
Поэтому обращения
cout.setf(ios::oct,ios::basefield); // восьмеричное
cout.setf(ios::dec,ios::basefield); // десятичное
cout.setf(ios::hex,ios::basefield); // шестнадцатеричное
установят систему счисления, не затрагивая других компонентов состояния
потока. Если система счисления установлена, она используется до явной
переустановки, поэтому
cout << 1234 << ' '; // десятичное по умолчанию
cout << 1234 << ' ';
cout.setf(ios::oct,ios::basefield); // восьмеричное
cout << 1234 << ' ';
cout << 1234 << ' ';
cout.setf(ios::hex,ios::basefield); // шестнадцатеричное
cout << 1234 << ' ';
cout << 1234 << ' ';
напечатает
1234 1234 2322 2322 4d2 4d2
Если появится необходимость указывать систему счисления для каждого
выдаваемого числа, следует установить флаг showbase. Поэтому, добавив
перед приведенными выше обращениями
cout.setf(ios::showbase);
мы получим
1234 1234 02322 02322 0x4d2 0x4d2
Стандартные манипуляторы, приведенные в $$10.4.2.1, предлагают более
элегантный способ определения системы счисления при выводе целых.
10.4.1.5 Выравнивание полей
С помощью обращений к setf() можно управлять расположением символов
в пределах поля:
cout.setf(ios::left,ios::adjustfield); // влево
cout.setf(ios::right,ios::adjustfield); // вправо
cout.setf(ios::internal,ios::adjustfield); // внутреннее
Будет установлено выравнивание в поле вывода, определяемом функцией
ios::width(), причем не затрагивая других компонентов состояния потока.
Выравнивание можно задать следующим образом:
cout.width(4);
cout << '(' << -12 << ")\n";
cout.width(4);
cout.setf(ios::left,ios::adjustfield);
cout << '(' << -12 << ")\n";
cout.width(4);
cout.setf(ios::internal,ios::adjustfield);
cout << '(' << -12 << "\n";
что выдаст
( -12)
(-12 )
(- 12)
Если установлен флаг выравнивания internal (внутренний), то символы
добавляются между знаком и величиной. Как видно, стандартным является
выравнивание вправо.
Достарыңызбен бөлісу: |