Базовые потоки ввода-вывода

 

Для ввода с потока используются объекты класса istream, для вывода в поток – объекты класса ostream.

В классе istream определены следующие функции:

istream& get(char* buffer,int size,char delimiter=’\n’);

Эта функция извлекает символы из istream и копирует их в буфер. Операция прекращается при достижении конца файла, либо при скопировании size символов, либо при обнаружении указанного разделителя. Сам разделитель не копируется и остается в streambuf. Последовательность прочитанных символов всегда завершается нулевым символом.

istream& read(char* buffer,int size);

Не поддерживает разделителей, и считанные в буфер символы не завершаются нулевым символом.

istream& getline(char* buffer,int size, char delimiter=’\n’);

Разделитель извлекается из потока, но в буфер не заносится. Это основная функция для извлечения строк из потока. Считанные символы завершаются нулевым символом.

istream& get(streambuf& s,char delimiter=’\n’);

Копирует данные из istream в streambuf до тех пор, пока не обнаружит конец файла или символ-разделитель, который не извлекается из istream. В s нулевой символ не записывается.

istream get (char& С);

Читает символ из istream в С. В случае ошибки С принимает значение 0XFF.

int get();

Извлекает из istream очередной символ. При обнаружении конца файла возвращает EOF.

int peek();

Возвращает очередной символ из istream, не извлекая его из istream.

int gcount();

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

istream& putback(С)

Если в области get объекта streambuf есть свободное пространство, то туда помещается символ С.

istream& ignore(int count=1,int target=EOF);

Извлекает символ из istream, пока не произойдет следующее:

- функция не извлечет count символов;

- не будет обнаружен символ target;

- не будет достигнуто конца файла.

В классе ostream определены следующие функции:

ostream& put(char C);

Помещает в ostream символ С.

ostream& write(const char* buffer,int size);

Записывает в ostream содержимое буфера. Символы копируются до тех пор, пока не возникнет ошибка или не будет скопировано size символов. Буфер записывается без форматирования. Обработка нулевых символов ничем не отличается от обработки других. Данная функция осуществляет передачу необработанных данных (бинарных или текстовых) в ostream.

 

ostream& flush();

Сбрасывает буфер streambuf.

 

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

При чтении

istream& seekg(long p);

Устанавливает указатель потока get (не путать с функцией) со смещением р от начала потока.

istream& seekg(long p,seek_dir point);

Указывается начальная точка перемещения.

enum seek_dir{beg,curr,end}

Положительное значение р перемещает указатель get вперед (к концу потока), отрицательное значение р – назад (к началу потока).

long tellg();

Возвращает текущее положение указателя get.

При записи.

ostream& seekp(long p);

Перемещает указатель put в streambuf на позицию р от начала буфера streambuf.

ostream& seekp(long p,seek_dir point);

Указывает точка отсчета.

long tellp();

Возвращает текущее положение указателя put.

 

Помимо этих функций в классе istream перегружена операция >>, а в классе ostream <<. Операции << и >> имеют два операнда Левым операндом является объект класса istream (ostream), а правым – данное, тип которого задан в языке.

Для того чтобы использовать операции << и >> для всех стандартных типов данных используется соответствующее число перегруженных функций operator<< и operator>>. При выполнении операций ввода-вывода в зависимости от типа правого операнда вызывается та или иная перегруженная функция operator.

Поддерживаются следующие типы данных: целые, вещественные, строки (char*). Для вывода – void* (все указатели, отличные от char*, автоматически переводятся к void*). Перегрузка операции >> и << не изменяет их приоритета.

Функции operator<< и operator>>возвращают ссылку на тот потоковый объект, который указан слева от знака операции. Таким образом, можно формировать “цепочки ” операций.

cout << a << b << c;

cin >> i >> j >> k;

При вводе-выводе можно выполнять форматирование данных.

Чтобы использовать операции >> и << с данными пользовательских типов, определяемых пользователем, необходимо расширить действие этих операций, введя новые операции-функции. Первым параметром операции-функции должна быть ссылка на объект потокового типа, вторым – ссылка или объект пользовательского типа.

В файле iostream.h определены следующие объекты, связанные со стандартными потоками ввода-вывода:

cin – объект класса istream, связанный со стандартным буферизированным входным потоком;

cout – объект класса ostream, связанный со стандартным буферизированным выходным потоком;

cerr – не буферизированный выходной поток для сообщения об ошибках;

clog – буферизированный выходной поток для сообщения об ошибках.

Форматирование

 

Непосредственное применение операций ввода << и вывода >> к стандартным потокам cout, cin, cerr, clog для данных базовых типов приводит к использованию “умалчиваемых” форматов внешнего представления пересылаемых значений.

Форматы представления выводимой информации и правила восприятия данных при вводе могут быть изменены программистом с помощью флагов форматирования. Эти флаги унаследованы всеми потоками из базового класса ios. Флаги форматирования реализованы в виде отдельных фиксированных битов и хранятся в protected компоненте класса long x_flags. Для доступа к ним имеются соответствующие public функции.

Кроме флагов форматирования используются следующие protected компонентные данные класса ios:

int x_width – минимальная ширина поля вывода.

int x_precision – точность представления вещественных чисел (количество цифр дробной части) при выводе;

int x_fill – символ-заполнитель при выводе, пробел – по умолчанию.

Для получения (установки) значений этих полей используются следующие компонентные функции:

int width();

int width(int);

int precision();

int precision(int);

char fill();

char fill(char);

Манипуляторы

 

Несмотря на гибкость и большие возможности управления форматами с помощью компонентных функций класса ios, их применение достаточно громоздко. Более простой способ изменения параметров и флагов форматирования обеспечивают манипуляторы.

Манипуляторами называются специальные функции, позволяющие модифицировать работу потока. Особенность манипуляторов состоит в том, что их можно использовать в качестве правого операнда операции >> или <<. В качестве левого операнда, как обычно, используется поток (ссылка на поток), и именно на этот поток воздействует манипулятор.

Для обеспечения работы с манипуляторами в классах istream и ostream имеются следующие перегруженные функции operator.

istream& operator>>(istream&(*_f)( istream&));

ostream& operator<<(ostream&(*_f)(ostream&));

При использовании манипуляторов следует включить заголовочный файл <iomanip.h>, в котором определены встроенные манипуляторы.