Г. Шилтд - Самоучитель C++ (DJVU) (1114955), страница 36
Текст из файла (страница 36)
Обычно, если вы задаете иерархию классов, вы начинаете с более класса и продолжаете более классом. (Впишите пропущенные слова.) Самоучитель С++ 8.1. Некоторые базовые положения системы ввода/вывода С++ Перед тем как начать обсуждение системы ввода/вывода С++, несколько общих комментариев. Система ввода/вывода С++, так же, как система ввода/вывода С, действует через лотоки ~агеая4. Поскольку вы программировали на С, вы уже должны знать, что такое поток ввода/вывода, однако несколько дополнительных замечаний обобщат ваши знания.
Поток ввода/вывода — это логическое устройство, которое выдает и принимает пользовательскую информацию. Поток связан с физическим устройством с помощью системы ввода/вывода С++. Поскольку все потоки ввода/вывода действуют одинаково, то, несмотря на то, что программисту приходится работать с совершенно разными по характеристикам устройствами, система ввода/вывода предоставляет для этого единый удобный интерфейс. Например, функция, которая используется для записи информации на экран монитора, вполне подойдет как для записи в файл, так и для вывода на принтер. Как вы знаете, если программа на С начинает выполняться, открываются три потока: зП11п, вЫоп1 и вЫегг. Нечто похожее имеет место при запуске программ на С++.
Когда запускается программа на С++, автоматически открываются четыре потока: Поток Значение Устройство по умолчанию Клавиатура Экран Экран Экран Стандартный ввод Стандартный вывод Стандартная ошибка соо1 сегг с!оц Буферизуемая версия сегг Как вы, наверное, уже догадались, потоки с1п, соп1 и сегг соответствуют потокам Мйп, зЫоп1 и зП1егг языка С. Потоками с!п и сонг вы уже пользовались. Поток с1оп — это просто буферизуемая версия потока еегг. В языке Мандата С++ также открываются дополнительные потоки тге1п, тусей, тгеегг и ттс1оп, предназначенные для широких (16-разрядных) символов, которые в данной книге не рассматриваются. Эти потоки обеспечивают передачу расширенных наборов символов (1агце с)тагасгег зегз), что обеспечивает возможность работы с некоторыми экзотическими языками, такими как, например, китайский.
По умолчанию, стандартные потоки используются для связи с клавиатурой и экраном. Однако в среде, в которой поддерживается переопределение ввода/вывода, эти потоки могут быть перенаправлены на другие устройства. Как отмечалось в главе 1, в С++ ввод/вывод обеспечивается подключением к программе заголовочного файла <1ов1геагп>. В этом файле определены сложные наборы иерархий классов, поддерживающие операции ввода/вывода. Классы ввода/вывода начинаются с системы классов-шаблонов 1/сир/атес!азгев). Глава 8.
Неадеиие в систему ввода/вывода С.!-!- 243 Подробно о классах-шаблонах, называемых также родовыми классами (лепет)с с1аввев), будет рассказано в главе 11, сейчас же ограничимся кратким комментарием. В классе-шаблоне определяется только форма класса без полного задания данных, с которыми он работает. После того как класс-шаблон определен, появляется возможность создавать отдельные экземпляры этого класса.
Что касается библиотеки ввода/вывода, то 8гапс1агс1 С++ создает две разные версии классов-шаблонов ввода/вывода: одну для 8-разрядных символов, а другую для широких (16-разрядных) символов. В данной книге рассказывается только о классах для 8-разрядных символов, поскольку именно они используются чаще всего.
Система ввода/вывода С++ строится на двух связанных, но различных иерархиях классов-шаблонов. Первая является производной от класса нижнего уровня Ьав!с йгеавтЬцГ. Этот класс предоставляет базу для операций нижнего уровня по вводу и выводу, а также обеспечивает надлежащую поддержку всей системы ввода/вывода С++. До тех пор, пока вы не погрузитесь в самые основы программирования ввода/вывода, непосредственно использовать класс Ьав1с вФгеагвЪИ вам не понадобиться. Иерархия классов, с которой вам чаще всего придется иметь дело, является производной от класса Ьав1с 1ов. Это класс ввода/вывода верхнего уровня, который обеспечивает форматирование, контроль ошибок и информацию о состоянии потока ввода/вывода. Класс Ьаяс юв является базовым для нескольких производных классов, среди которых классы Ьав1с Матея!!в, Ьаайс оа$геаш и Ьав|с !овггеаип.
Эти классы используются соответственно для создания потоков ввода, вывода и ввода/вывода. Как уже говорилось, библиотека ввода/вывода создает две отдельные версии иерархий классов: одну для 8-разрядных символов и другую для широких символов. В представленной ниже таблице показано соответствие имен классов-шаблонов их версиям для 8-разрядных символов (включая и те, о которых будет рассказано в главе 9).
Класс для 6-резряднык символов в1геагпЬц1 юв Имена классов для 8-разрядных символов будут употребляться далее на всем протяжении книги, поскольку как раз эти имена и следует указывать в Класс-шаблон Ьав!с в1геагпЬиг Ьав!с !ов Ьав!с !в1геагп Ьав!с ов1геагп Ьав!с 1овГгеагп Ьав!с гвГгеагп Ьав1с 1Гвггеагп Ьав1с огвГгеа!и !в1геагп ов1геагп юв1геагп Мгеагп !тв1геагп о1в1геаго Самоучитель Сч-г 244 программах. Это именно те имена, которые использовались в прежней библиотеке ввода/вывода, и именно по этой причине на уровне исходного кода совместимы старая и новая библиотеки ввода/вывода.
И последнее замечание: в классе !оз содержится множество функций и переменных — членов класса, которые контролируют или отображают основные операции потока ввода/вывода. Вы еще часто будете сталкиваться с классом !оз. Запомните: чтобы получить доступ к этому важному классу, необходимо включить в программу заголовок <1еяФгеап!>. 8.2. Форматируемый ввод/вывод До сих пор во всех примерах этой книги для вывода информации на экран использовались форматы, заданные в С++ по умолчанию.
Однако информацию можно выводить в широком диапазоне форм. При этом с помощью системы ввода/вывода С++ можно форматировать данные так же, как это делала в С функция рта). Кроме того, можно изменять определенные параметры ввода информации. Каждый поток ввода/вывода связан с набором флагов формата (Гогша1 Йаяз), которые управляют способом форматирования информации и представляют собой битовые маски !Ъ|гтахЬ). Эти маски объявлены в классе 1оз как данные перечислимого типа 6а$йавя, в котором определены следующие значения: аб1еа!!1е!б ЬааеЯе1б Ьос1а1рьа !1аа111е1б а|чрчге ипИЬот иррегсаае г!сЬ! Ьех ес!естес ебочуЬаее аб овгро! п1 евочгреа 1гбегпа! 1ей бес т!хеб осг Эти значения определены в классе !оз и необходимы для установки или сброса флагов формата.
Если вы пользуетесь устаревшим, нестандартным компилятором, может оказаться, что перечислимый тип данных Йп1йацз в нем не определен. В таких компиляторах для хранения флагов формата отводится длинное целое. Когда при вводе информации в поток установлен флаг я)прия, начальные невидимые символы (пробелы, табуляции и символы новой строки) отбрасываются. Когда флаг й)ряб сброшен, невидимые символы не отбрасываются. Когда установлен флаг 1ей, происходит выравнивание вывода по левому краю, Когда установлен флаг г1ф1, происходит выравнивание вывода по правому краю.
Когда установлен флаг 1п1егва1, для заполнения поля вывода происходит вставка пробелов между всеми цифрами и знаками числа. Если все эти флаги не установлены, то по умолчанию используется выравнивание по правому краю. Глава 8. Введение в систему ввода/вывода С++ По умолчанию числовые значения выводятся в десятичной системе счисления. Однако основание системы счисления можно поменять. Установка флага ое1 ведет к тому, что вывод будет осуществляться в восьмеричной системе счисления, а установка флага Ьех — в шестнадцатеричной. Чтобы вернуться к десятичной системе счисления, установите флаг бес.
Установка флага йоиЬаяе ведет к выводу основания системы счисления. Например, шестнадцатеричное значение 1Р с этим флагом будет выводиться как Ох1Р. По умолчанию при выводе значений в научной нотации символ "е" выводится в нижнем регистре. Кроме этого, при выводе шестнадцатеричного значения символ "х" тоже выводится в нижнем регистре.
При установке флага пррегсахе, эти символы выводятся в верхнем регистре. Установка флага аЬоууроя приводит к выводу знака + перед положительными значениями. Установка флага аЬо(гроЫ ведет к появлению десятичной точки и последующих нулей при выводе любых значений с плавающей точкой. При установке фла~а яс(еп(1Йс числа с плавающей точкой выводятся в научной нотации. При установке флага Йхед числа с плавающей точкой выводятся в обычной нотации. Если ни один из этих флагов не установлен, компилятор сам выбирает подходящий способ вывода. Если установлен флаг шй1Ы; то буфер очищается (ПцзЬ) после каждой операции вставки (1пзег(1оп орега(1оп). При установленном флаге Ь(иг1а1рйа значения булева типа выводятся в виде ключевых слов 1гпе и Ыяе.
Одновременно на все поля, определенные с флагами ос(, бес и Ьех, можно сослаться с помощью флага ЬмейеИ. Аналогично на поля, определенные с флагами 1ей, пяЬ( и 1п(егпа1, можно сослаться с помощью флага а4ы(ЙеЬ1 И наконец, на поля с флагами яс(еп(Жс и Йхе(1 можно сослаться с помощью флага Йоа(йе16. Для установки флага формата пользуйтесь функцией яе6(). Эта функция является членом класса 1оз. Здесь показана ее основная форма: йшей1адв евес (йвеЕ1аде Флатвт) г Эта функция возвращает предыдущие установки флагов формата и устанавливает новые, заданные значением флаги.
(Значения всех остальных флагов не изменяются.) Например, для установки флага яЬоъроя можно воспользоваться следующей инструкцией: жжем ивсде/вывода. ееЕс (~ое:: еЬомраа) Здесь потогг ввода/вывода — это тот поток, на который вы хотите повлиять. Обратите внимание на использование оператора расширения области види- Самоучитель С+-)- мости. Запомните, флаг в))одров — это перечислимая константа внутри класса юв. Следовательно, чтобы сообщить компилятору об этом, необходимо поставить перед флагом в!)одров имя класса и оператор расширения области видимости.
Если этого не сделать, константа йовров просто не будет распознана компилятором. Важно понимать, что функция яеМ() является членом класса )оз и влияет на созданные этим классом потоки ввода/вывода. Поэтому любой вызов функции веЩ) делается относительно конкретного потока.