Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
369164_46F07_otvety_na_bilety_po_oop_si.doc
Скачиваний:
44
Добавлен:
24.12.2018
Размер:
613.38 Кб
Скачать

42. Состояния потока. Ошибки потоков. Состояние потока

Каждый поток имеет связанное с ним состояние. Состояния потока описываются в классе ios в виде перечисления enum.

public:

enum io_state {

goodbit, // нет ошибки 0Х00

eofbit, // конец файла 0Х01

failbit, // последняя операция не выполнилась 0Х02

badbit, // попытка использования недопустимой операции 0Х04

hardfail // фатальная ошибка 0Х08

};

Флаги, определяющие результат последней операции объектом ios, содержатся в переменной state. Получить значение этой переменной можно с помощью функции int rdstate().

Кроме того, проверить состояние потока можно следующими функциями:

int bad(void); // 1, badbit или hardfail

int eof(void); // 1, если eofbit

int fail(void); // 1, если failbit, badbit или hardfail

int good(void); // 1, если goodbit

Если операция >> используется для новых типов данных, то при её перегрузке необходимо предусмотреть соответствующие проверки.

Пользователей библиотеки iostream, разумеется, интересует, находится ли поток в ошибочном состоянии. Например, если мы пишем

int ival;

cin >>ival;

и вводим слово "Borges", то cin переводится в состояние ошибки после неудачной попытки присвоить строковый литерал целому числу. Если бы мы ввели число 1024, то чтение прошло бы успешно и поток остался бы в нормальном состоянии.

Чтобы выяснить, в каком состоянии находится поток, достаточно проверить его значение на истину:

if ( !cin )

// операция чтения не прошла или встретился конец файла

Для чтения заранее неизвестного количества элементов мы обычно пишем цикл while:

while ( cin >> word )

// операция чтения завершилась успешно ...

Условие в цикле while будет равно false, если достигнут конец файла или произошла ошибка при чтении. В большинстве случаев такой проверки потокового объекта достаточно. Однако при реализации оператора ввода для класса WordCount из раздела 20.5 нам понадобился более точный анализ состояния.

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

  • eof() возвращает true, если достигнут конец файла:

if ( inOut.eof() )

// отлично: все прочитано ...

  • bad() возвращает true при попытке выполнения некорректной операции, например при установке позиции за концом файла. Обычно это свидетельствует о том, что поток находится в состоянии ошибки;

  • fail() возвращает true, если операция завершилась неудачно, например не удалось открыть файл или передан некорректный формат ввода:

ifstream iFile( filename, ios_base::in );

if ( iFile.fail() ) // не удалось открыть

error_message( ... );

  • good() возвращает true, если все вышеперечисленные условия ложны:

if ( inOut.good() )

43. Форматирование в си++. Форматирующие функции-члены. Форматирующие функции – элементы, изменяющие флаги форматирования. Управление потоков с помощью манипулятора.

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

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

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

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

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

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

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

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

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

int width(void);

int width(int);

int precision(void);

int precision(int);

char fill(void);

char fill(char);

форматирующие функции-члены. Их всего три: width(), precision() и fill().

По умолчанию при выводе любого значения оно занимает столько позиций, сколько символов выводится. Функция width() позволяет задать минимальную ширину поля для вывода значения. При вводе она задает максимальное число читаемых символов. Если выводимое значение имеет меньше символов, чем заданная ширина поля, то оно дополняется символами-заполнителями до заданной ширины (по умолчанию - пробелами). Если же выводимое значение имеет больше символов, чем ширина отведенного ему поля, то поле будет расширено до нужного размера. Эта функция имеет следующие прототипы:

int width(int wide);      int width() const;

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

Функция precision() позволяет узнать или задать точность (число выводимых цифр после десятичной точки), с которой выводятся числа с плавающей точкой. По умолчанию числа с плавающей точкой выводятся с точностью, равной шести цифрам. Функция precision () имеет следующие прототипы:

int precision(int prec);      int precision() const;

Функция с первым прототипом устанавливает точность в prec и возвращает предыдущую точность. Функция со вторым прототипом возвращает текущую точность.

Функция fill() позволяет прочесть или установить символ-заполнитель. Она имеет следующие прототипы:

char fill(char type ch);      char fill() const;

Функция с первым прототипом устанавливает ch в качестве текущего символа-заполнителя и возвращает предыдущий символ-заполнитель. Функция со вторым прототипом возвращает текущий символ-заполнитель. По умолчанию в качестве символа-заполнителя используется пробел.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]