За исключением того, что функция ввода должна возвращать ссылку на объект типа istream
, тело этой функции может содержать все, что вы считаете нужным в нее включить. Но логичнее использовать операторы ввода все же по прямому назначению, т.е. для выполнения операций ввода.Сравнение С- и С++-систем ввода-вывода
Как вы знаете, предшественник C++, язык С, оснащен одной из самых гибких (среди структурированных языков) и при этом очень мощных систем ввода-вывода. (Не будет преувеличением сказать, что среди всех известных структурированных языков С-система ввода-вывода не имеет себе равных.) Почему же тогда, спрашивается, в C++ определяется собственная система ввода-вывода, если в ней продублирована большая часть того, что содержится в С (имеется в виду мощный набор С-функций ввода-вывода)? Ответить на этот вопрос нетрудно. Дело в том, что С-система ввода-вывода не обеспечивает никакой поддержки для объектов, определяемых пользователем. Например, если создать в С такую структуру
struct my_struct {
int count;
char s [80];
double balance;
} cust;
то существующую в С систему ввода-вывода невозможно настроить так, чтобы она могла выполнять операции ввода-вывода непосредственно над объектами типа my_struct
. Но поскольку центром объектно-ориентированного программирования являются именно объекты, имеет смысл, чтобы в C++ функционировала такая система ввода-вывода, которую можно было бы динамически "обучать" обращению с любыми объектами, создаваемыми программистом. Именно поэтому для C++ и была изобретена новая объектно-ориентированная система ввода-вывода. Как вы уже могли убедиться, С++-подход к вводу-выводу позволяет перегружать операторы "<<" и ">>", чтобы они могли работать с классами, создаваемыми программистами.И еще. Поскольку C++ является супермножеством языка С, все содержимое С-системы ввода-вывода включено в C++. (См. приложение А, в котором представлен обзор С-ориентированных функций ввода-вывода.) Поэтому при переводе С-программ на язык C++ вам не нужно изменять все инструкции ввода-вывода подряд. Работающие С-инструкции скомпилируются и будут успешно работать и в новой С++-среде. Просто вы должны учесть, что старая С-система ввода-вывода не обладает объектно-ориентированными возможностями.
Форматированный ввод-вывод данных
До сих пор при вводе или выводе информации в наших примерах программ действовали параметры форматирования, которые по умолчанию использует С++-система ввода-вывода. Но программист может сам управлять форматом представления данных, причем двумя способами. Первый способ предполагает использование функций-членов класса ios
, а второй— функций специального типа, именуемых манипуляторами (manipulator). Мы же начнем освоение возможностей форматирования с функций-членов класса ios.Форматирование данных с использованием функций-членов класса ios
В системе ввода-вывода C++ каждый поток связан с набором флагов форматирования, которые управляют процессом форматирования информации. В классе ios
объявляется перечисление fmtflags, в котором определены следующие значения. (Точнее, эти значения определены в классе ios_base, который, как упоминалось выше, является базовым для класса ios.)
Эти значения используются для установки или очистки флагов форматирования с помощью таких функций, как setf()
и unsetf(). При использовании старого компилятора может оказаться, что он не определяет тип перечисления fmtflags. В этом случае флаги форматирования будут кодироваться как целочисленные long-значения.
Если флаг skipws
установлен, то при потоковом вводе данных ведущие "пробельные" символы, или символы пропуска (т.е. пробелы, символы табуляции и новой строки), отбрасываются. Если же флаг skipws сброшен, пробельные символы не отбрасываются.
Если установлен флаг left
, выводимые данные выравниваются по левому краю, а если установлен флаг right — по правому. Если установлен флаг internal, числовое значение дополняется пробелами, которыми заполняется поле между ним и знаком числа или символом основания системы счисления. Если ни один из этих флагов не установлен, результат выравнивается по правому краю по умолчанию.
По умолчанию числовые значения выводятся в десятичной системе счисления. Однако основание системы счисления можно изменить. Установка флага oct
приведет к выводу результата в восьмеричном представлении, а установка флага hex — в шестнадцатеричном. Чтобы при отображении результата вернуться к десятичной системе счисления, достаточно установить флаг dec.
Установка флага showbase
приводит к отображению обозначения основания системы счисления, в которой представляются числовые значения. Например, если используется шестнадцатеричное представление, то значение 1F будет отображено как 0x1F.