Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП Лекции PDF / ООП 10 Лек Потоковый ввод-вывод.pdf
Скачиваний:
63
Добавлен:
15.02.2015
Размер:
447.65 Кб
Скачать

Лекция 10

Потоковый ввод-вывод

1

 

Л Е К Ц И Я 1 0

 

ПРЕДОПРЕДЕЛЕННЫЕ ПОТОКИ_________________________________________________________ 1 ПРЕИМУЩЕСТВА БИБЛИОТЕКИ ПОТОКОВ C++ _________________________________________ 3

Безопасность типов _____________________________________________________________________ 3 Расширяемость для новых типов__________________________________________________________ 3 Простота и последовательность___________________________________________________________ 3

ОПЕРАЦИИ ПОМЕЩЕНИЯ И ИЗВЛЕЧЕНИЯ ИЗ ПОТОКА _________________________________ 3

Оператор помещения в поток_____________________________________________________________ 3 Оператор извлечения из потока ___________________________________________________________ 4

ФОРМАТИРОВАНИЕ ПОТОКА ___________________________________________________________ 5

Форматирующие функции-члены __________________________________________________________ 5 Флаги форматирования__________________________________________________________________ 6 Манипуляторы ввода-вывода _____________________________________________________________ 7

ФАЙЛОВЫЙ ВВОД-ВЫВОД С ИСПОЛЬЗОВАНИЕМ ПОТОКОВ ____________________________ 8

НЕФОРМАТИРУЕМЫЙ ВВОД-ВЫВОД___________________________________________________ 10

Функции ввода-вывода _________________________________________________________________ 11 Файлы с произвольным доступом_________________________________________________________ 13 Опрос и установка состояния потока ______________________________________________________ 13 Перегрузка операторов извлечения и вставки ______________________________________________ 15 Переадресация ввода-вывода ___________________________________________________________ 16

ПРЕДОПРЕДЕЛЕННЫЕ ПОТОКИ

На протяжении этой книги мы регулярно пользовались стилем ввода-вывода C++, не вникая в детали его реализации. Теперь самое время заняться изучением реализации потоков ввода-вывода. Наряду с функциями библиотеки времени выполнения, предназначенными для ввода-вывода, в C++ включен дополнительный набор объектно-ориентированных подпрограмм ввода-вывода. Главным преимуществом системы ввода-вывода C++ является то, что она может перегружаться для создаваемых вами классов.

В настоящее время используются новая версия библиотеки ввода-вывода, которая широко использует шаблоны классов. Поскольку мы еще не рассмотрели использование шаблонов классов, эти детали реализации мы будем опускать.

Поток ввода-вывода – это логическое устройство, предназначенное для приема и выдачи информа-

ции пользователю. Поток связан с физическим устройством с помощью системы ввода-вывода C++. По-

ток обеспечивает пользователю единый интерфейс при работе с системой ввода-вывода. Это означа-

ет, что, например, для вывода информации на экран монитора и для записи ее в файл используется одна и та же функция.

Когда программа на C++ начинает выполняться, автоматически создаются восемь предопределенных стандартных потоков. Эти стандартные потоки связаны со стандартными файлами языка C следующим образом:

поток для "узких" символов

cin

cout

cerr

clog

поток для "широких" символов

wcin

wcout

wcerr

wclog

стандартный файл языка C

stdin

stdout

stderr

stderr

Все эти потоки и стандартные файлы языка C по умолчанию связаны с терминалом. Объект cin управляет вводом из буфера потока, связанного с объектом stdin, объявленным в <cstdio>. По умолчанию эти два потока синхронизированы.

Объект cout управляет буфером потока, связанным с объектом stdout, объявленным в <cstdio>. По умолчанию эти два потока также синхронизированы.

Поток clog – это просто буферизованная версия потока cerr. В буферизованной версии потока запись на реальное внешнее устройство делается, только когда буфер полон. Поэтому clog является более эффективным для перенаправления вывода в файл, в то время как cerr используется главным образом для вывода на экран терминала.

Система ввода-вывода содержит две иерархии классов:

первая предназначена для работы с ASCII-символами, имеющими длину 8 бит; вторая предназначена для работы с UNICODE-символами, имеющими длину 16 бит. Символы первого набора называются "узкими", а второго – "широкими".

В основе иерархии потоковых классов лежит класс basic_ios, который в качестве своего подобъекта содержит абстрактный класс basic_streambuf. Последний является базовым классом для создания буфе-

Выжол Ю.А.

Объектно-ориентированное программирование

Лекция 10

Потоковый ввод-вывод

2

ра потока, который управляет передачей элементов в поток и из него для специализированных видов потоков.

Класс basic_ios является базовым для нескольких производных классов, среди которых классы basic_istream, basic_ostream и basic_iostream. Он содержит наиболее общие функции, необходимые для всех потоков, и обслуживает информацию о состоянии, которая отражает целостность потока и буфер потока. Этот класс также обслуживает связь потоковых классов с классами буферов потоков с помощью функции-члена rdbuf ( ). Классы, производные от basiс_ios, специализируют операции ввода-вывода. В свою очередь, basic_ios использует класс ios_base, который также является базовым классом для всех потоковых классов. Он не зависит от типа символов и инкапсулирует информацию, необходимую для всех потоков. Эта информация включает в себя:

управляющую информацию для синтаксического анализа и форматирования;

дополнительную информацию для нужд пользователя (которая предоставляет путь для расширения потоков);

наполнение потока региональными (или локальными) символами.

Кроме того, этот класс определяет несколько типов данных, используемых всеми потоковыми классами, такие как флаги форматирования, биты состояния, режимы открытия файлов и т.д.

С целью обеспечения совместимости с традиционной версией библиотеки ввода-вывода C++ введены синонимы для имен потоковых классов:

Шаблон класса

Синоним

Шаблон класса

Синоним

basic_ios

ios

basic_ifstream

ifstream

basic_istream

istream

basic_ofstream

ofstream

basic_оstream

оstream

basic_fstream

fstream

basic_iostream

iostream

basic_streambuf

streambuf

Имена синонимов в точности соответствуют именам потоковых классов в традиционной версии библиотеки ввода-вывода C++. Далее при изложении потокового ввода-вывода и мы будем пользоваться этими именами, поскольку как раз эти имена следует указывать в программах.

Библиотека ввода-вывода содержит два параллельных семейства классов: одно – производное от streambuf и второе – производное от ios. Оба эти класса являются низкоуровневыми, выполняющими различный вид задач. Все потоковые классы имеют, по крайней мере, один из этих классов в качестве базового. Доступ из ios-производных классов к streambuf-производным осуществляется через указатель. Класс streambuf обеспечивает интерфейс с памятью и физическими устройствами. Функции-члены семейства классов streambuf используются ios-производными классами.

Назначение классов потокового ввода-вывода следующее:

istream

потоковый класс общего назначения для ввода, являющийся базовым клас-

ifstream

сом для других потоков ввода;

потоковый класс для ввода из файла;

istream_withassign

потоковый класс ввода для cin;

istrstrearm

потоковый класс для ввода строк;

оstream

потоковый класс общего назначения для вывода, являющийся базовым

ofstream

классом для других потоков вывода;

потоковый класс для вывода в файл;

ostream_withassign

потоковый класс ввода для cout, cerr, clog;

ostrstream

потоковый класс для вывода строк;

iostream

потоковый класс общего назначения для ввода-вывода, являющийся базо-

fstream

вым классом для других потоков ввода-вывода;

потоковый класс для ввода-вывода в файл;

strstream

потоковый класс для ввода-вывода строк;

stdiostream

класс для ввода-вывода в стандартные файлы ввода-вывода;

streambuf

абстрактный базовый класс буфера потока;

filebuf

класс буфера потока для дисковых файлов;

strstreambuf

класс буфера потока для строк;

stdiobuf

класс буфера потока для стандартных файлов ввода-вывода.

Назначение почти всех классов следует из их названия. Классы группы _withassign являются производными соответствующих потоковых классов без этого окончания. Они перегружают оператор присваивания, что позволяет изменять указатель на используемый классом буфер. Если подключен заголовочный файл <iostream>, программы, написанные на языке C++, начинают выполняться с четырьмя открытыми

Выжол Ю.А.

Объектно-ориентированное программирование