Система классов ввода-вывода




Классы для ввода-вывода потоков

Система ввода-вывода С++ основывается на концепции потоков данных, поток представляет собой, с одной стороны, последовательность данных, с другой стороны поток рассматривается как переменная некоторого объектного типа. Это позволяет вынести общие свойства и операции процессов ввода-вывода в определения базовых классов. Ввод-вывод из файлов и консоли, как правило, выполняется с использованием буфера и получение данных программой или вывод данных сводится к пересылке данных из одной области памяти в другую. Реальное обращение к внешним устройствам происходит только при исчерпании данных в буфере (при вводе) или при заполнении буфера (при выводе).

Система классов ввода-вывода С++ использует два базовых класса: класс ios и класс streambuf.

В классе ios определены данные, характеризующие состояние потока, и функции, позволяющие получить доступ к информации о состоянии потока или изменить его состояние. Состояние потока определяется набором битовых флагов, для обращения к отдельным флагам в классе ios описаны перечислимые константы:

- биты состояния (статуса) потока

enum io_state { goodbit = 0x00, // никакие биты не установлены, все хорошо eofbit = 0x01, // конец файла failbit = 0x02, // ошибка в последней операции ввода/вывода badbit = 0x04, // попытка выполнить неверную операцию hardfail = 0x80 // неисправимая ошибка };

- биты режима использования потока (режима ввода/вывода)

enum open_mode { in = 0x01, // поток открыт для чтения out = 0x02, // поток открыт для записи ate = 0x04, // перейти в конец файла при открытии app = 0x08, // режим добавления в конец файла trunc = 0x10, // усечение существующего файла nocreate = 0x20, // ошибка открытия файла, если он не существует noreplace = 0x40, // ошибка открытия, если файл существует binary = 0x80 // двоичный (не текстовый) файл };

- флаги направления позиционирования в потоке

enum seek_dir { beg=0, cur=1, end=2 };

- флаги - манипуляторы управления вводом/выводом

enum { skipws = 0x0001, // пропускать пробелы при вводе left = 0x0002, // выравнивание влево при выводе right = 0x0004, // выравнивание вправо при выводе internal = 0x0008, // пробел после знака или основания системы счисления dec = 0x0010, // преобразование в десятичную систему счисления oct = 0x0020, // преобразование в восьмеричную систему счисления hex = 0x0040, // шестнадцатеричное преобразование showbase = 0x0080, // использовать индикатор системы счисления при выводе showpoint = 0x0100, // указывать десятичную точку при выводе //(в числах с плавающей точкой) uppercase = 0x0200, // прописные буквы при шестнадцатеричном выводе showpos = 0x0400, // добавлять '+' для положительных целых scientific= 0x0800, // применять нотацию вида 1.2345E2 fixed = 0x1000, // применять нотацию вида 123.45 unitbuf = 0x2000, // очищать все потоки после вставки в поток stdio = 0x4000, // очищать stdout, stderr после вставки в поток boolalpha = 0x8000 // вставлять/извлекать булевы как текст или цифры };

Поскольку эти перечислимые константы объявлены как компоненты класса ios, для доступа к ним требуется уточнение контекста, например, ios::in.

Класс streambuf обеспечивает создание и использование буфера ввода-вывода и содержит компоненты-данные для управления буфером и методы доступа к данным в буфере. Объект класса ios содержит указатель на связанный с ним объект streambuf.

Классы istream и ostream являются производными от класса ios, в них определены функции, выполняющие ввод (istream) и вывод (ostream) данных базовых типов и строк.

В классе istream определены операции бесформатного ввода (без преобразования вводимых данных)и операции форматного ввода с преобразованием из внешнего представления во внутреннее.

Функции get() читают из потока данные типа char в массив, определяемый первым параметром, второй параметр задает максимальное число вводимых символов (l), третий параметр устанавливает символ-ограничитель, ограничивающий ввод. За последним введенным символом в массив пишется символ ‘\0’.

istream _FAR & _RTLENTRY get(char _FAR *, int l, char = '\n');istream _FAR & _RTLENTRY get(signed char _FAR *, int l, char = '\n');istream _FAR & _RTLENTRY get(unsigned char _FAR *, int l, char ='\n');

Функции read() выполняют чтение из потока и занесение в массив указанного числа символов

istream _FAR & _RTLENTRY read(char _FAR *, int l);istream _FAR & _RTLENTRY read(signed char _FAR *, int l);istream _FAR & _RTLENTRY read(unsigned char _FAR *, int l);

Для ввода строки, заканчивающейся символом-ограничителем, служит функция getline() при этом символ-ограничитель также заносится в массив

istream _FAR & _RTLENTRY getline(char _FAR *, int, char = '\n');istream _FAR & _RTLENTRY getline(signed char _FAR *, int, char= '\n');istream _FAR & _RTLENTRY getline(unsigned char _FAR *, int, char= '\n');

Для извлечения из потока данных типа char вплоть до символа-ограничителя служит вариант функции get():

istream _FAR & _RTLENTRY get(streambuf _FAR &, char = '\n');

Другие варианты функции get() обеспечивают извлечение одного символа

istream _FAR & _RTLENTRY get(char _FAR &);istream _FAR & _RTLENTRY get(signed char _FAR &);istream _FAR & _RTLENTRY get(unsigned char _FAR &);int _RTLENTRY get(); // возвращает значение символаint _RTLENTRY peek(); // возвращает следующий символ без удаления его из потокаint _RTLENTRY gcount(); // число символов, извлеченных из потока // возвращение указанного символа в поток вводаistream _FAR & _RTLENTRY putback(char);

Пропуск символов с остановкой по ограничителю выполняет функция

istream _FAR & _RTLENTRY ignore(int = 1, int = EOF);

Форматный ввод релизуется на основе переопределения операций ввода

istream _FAR & _RTLENTRY operator>> (bool _FAR &);istream _FAR & _RTLENTRY operator>> (istream _FAR & (_RTLENTRY *_f)(istream _FAR &));istream _FAR & _RTLENTRY operator>> (ios _FAR & (_RTLENTRY *_f)(ios _FAR &));istream _FAR & _RTLENTRY operator>> (char _FAR *);istream _FAR & _RTLENTRY operator>> (signed char _FAR *);istream _FAR & _RTLENTRY operator>> (unsigned char _FAR *);istream _FAR & _RTLENTRY operator>> (char _FAR &);istream _FAR & _RTLENTRY operator>> (signed char _FAR &);istream _FAR & _RTLENTRY operator>> (unsigned char _FAR &);istream _FAR & _RTLENTRY operator>> (short _FAR &);istream _FAR & _RTLENTRY operator>> (int _FAR &);istream _FAR & _RTLENTRY operator>> (long _FAR &);istream _FAR & _RTLENTRY operator>> (unsigned short _FAR &);istream _FAR & _RTLENTRY operator>> (unsigned int _FAR &);istream _FAR & _RTLENTRY operator>> (unsigned long _FAR &);istream _FAR & _RTLENTRY operator>> (float _FAR &);istream _FAR & _RTLENTRY operator>> (double _FAR &);istream _FAR & _RTLENTRY operator>> (long double _FAR &);

Извлечение из istream и вставка в объект типа streambuf выполняет оператор-функция

istream _FAR & _RTLENTRY operator>> (streambuf _FAR *);

Макрос FAR управляет способом представления указателей, макрос RTLENTRY определяет применение стандартной билиотеки времени выполнения.

Аналогичные операции для вывода определены в классе ostream:

// вставить символ в потокostream _FAR & _RTLENTRY put(char); ostream _FAR & _RTLENTRY put(signed char);ostream _FAR & _RTLENTRY put(unsigned char);// вставить в поток строкуostream _FAR & _RTLENTRY write(const char _FAR *, int l);ostream _FAR & _RTLENTRY write(const signed char _FAR *, int l); ostream _FAR & _RTLENTRY write(const unsigned char _FAR *, int l);

Операции форматированного вывола

Вывод "true" или "false" для данных типа bool

ostream _FAR & _RTLENTRY ostream::operator<< (bool);

Вывод ланных типа char

ostream _FAR & _RTLENTRY operator<< (char);ostream _FAR & _RTLENTRY operator<< (signed char);ostream _FAR & _RTLENTRY operator<< (unsigned char);

Вывод числовых данных с преобразованием во внешнее представление

ostream _FAR & _RTLENTRY operator<< (short);ostream _FAR & _RTLENTRY operator<< (unsigned short);ostream _FAR & _RTLENTRY operator<< (int);ostream _FAR & _RTLENTRY operator<< (unsigned int);ostream _FAR & _RTLENTRY operator<< (long);ostream _FAR & _RTLENTRY operator<< (unsigned long);ostream _FAR & _RTLENTRY operator<< (float);ostream _FAR & _RTLENTRY operator<< (double);ostream _FAR & _RTLENTRY operator<< (long double);

Вывод строк, оканчивающихся нулевым байтом

ostream _FAR & _RTLENTRY operator<< (const char _FAR *);ostream _FAR & _RTLENTRY operator<< (const signed char _FAR*);ostream _FAR & _RTLENTRY operator<< (const unsigned char _FAR*);

Вывод значения указателя в символьном формате

ostream _FAR & _RTLENTRY operator<< (void _FAR *);

Извлечение данных их объекта streambuf и вставка в тот же ostream

ostream _FAR & _RTLENTRY operator<< (streambuf _FAR *);

Вывод значений манипуляторов

ostream _FAR & _RTLENTRY operator<< (ostream _FAR & (_RTLENTRY *_f)(ostream _FAR &));ostream _FAR & _RTLENTRY operator<< (ios _FAR & (_RTLENTRY *_f)(ios _FAR &));

Имеется также класс iostream, производный от класса ios и объединяющий возможности классов istream и ostream.

Для рассмотренных выше классов отсутствуют конструкторы копирования и операция присваивания, точнее, они объявлены, но не определены. Для тех случаев, когда конструктор копирования и операция присваивания необходимы, предусмотрены классы istream_withassign, ostream_withassign и iostream_withassign. Как экземпляры объектов этих классов всегда объявляется объект cin (экземпляр istream_withassign), обычно предназначенный для ввода с клавиатуры, и объекты cout, cerr и clog (экземпляры ostream_withassign), обычно предназначенные для вывода на экран.

Ввод-вывод для дисковых файлов обепечивается классами, описания которых содержатся в файле fstream.h.

Класс filebuf, производный от streambuf, предназначен для добавления в streambuf дополнительных средств управления буфером ввода-вывода.

Класс fstreambase, производный от класса ios, служит базой для остальных классов, обеспечивающих файловый ввод-вывод, в нем определены методы:

void _RTLENTRY open(const char _FAR *, int, int = filebuf::openprot);void _RTLENTRY attach(int);void _RTLENTRY close();void _RTLENTRY setbuf(char _FAR *, int);

Назначение этих методов очевидным образом следует из их названий.

Для непосредственной работы с файлами служат классы ifstream, ofstream и fstream, базой для них служат классы fstreambase и, соответственно, istream, ostream и iostream.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-04-20 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: