Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Затем итоговая программа прочитала бы исходные данные из файла и создала новый файл в формате (час, температура).

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

#include "std_lib_facilities.h"

struct Reading { // данные о температуре воздуха

int hour; // часы после полуночи [0:23]

double temperature; //
по Фаренгейту

Reading(int h, double t):hour(h), temperature(t) { }

};

int main

{

cout << "Пожалуйста, введите имя файла для ввода: ";

string name;

cin >> name;

ifstream ist(name.c_str); // поток ist считывает данные

// из файла,

// имя которого задано строкой name

if (!ist) error("Невозможно открыть файл для ввода ",name);

cout << "Пожалуйста, введите имя файла для вывода: ";

cin >> name;

ofstream ost(name.c_str); // поток ost записывает данные

// в файл, имя которого задано

// строкой name

if (!ost) error("Невозможно открыть файл для вывода ",name);

vector<Reading> temps; // здесь хранится считанная информация

int hour;

double temperature;

while (ist >> hour >> temperature) {

if (hour < 0 || 23 <hour) error("Некорректное время");

temps.push_back(Reading(hour,temperature));

}

for (int i=0; i<temps.size; ++i)

ost << '(' << temps[i].hour << ','

<< temps[i].temperature << ")\n";

}

10.6. Обработка ошибок ввода-вывода

Вводя данные, мы должны предвидеть ошибки и обрабатывать их. Какими бывают ошибки? Как их обрабатывать? Ошибки возникают из-за того, что их совершают люди (неправильно поняли инструкцию, сделали опечатку, по клавиатуре прошлась кошка и т.д.), из-за того, что файлы не соответствуют спецификациям, из-за того, что программисты имеют неправильное представление об ожидаемых данных, и т.д. Возможности для совершения ошибок при вводе данных ничем не ограничены! Однако поток

istream
сводит их все к четырем возможным классам, которые называют состояниями потока (stream state)

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

int i = 0;

cin >> i;

if (!cin) { // мы окажемся здесь (и только здесь),

// если операция ввода не выполнена

if (cin.bad) error("cin испорчен "); // поток поврежден: стоп!

if (cin.eof) {

// входных данных больше нет

// именно так мы хотели бы завершить ввод данных

}

if (cin.fail) { // с потоком что-то случилось

cin.clear; // приготовиться к дальнейшему вводу

// исправление ситуации

}

}

Выражение

!cin
можно прочитать как “поток
cin
в плохом состоянии”, или “с потоком
cin
что-то случилось”, или “поток
cin
не находится в состоянии
good
”. Это выражение противоположно по смыслу выражению “операция успешно завершена”. Обратите внимание на инструкцию
cin.clear
, в которой обрабатывается состояние
fail
. Если поток поврежден, то мы, вероятно, можем его восстановить. Для того чтобы сделать это, мы явно выводим поток из состояния
fail
и можем снова просматривать последовательность символов, находящихся в этом потоке; функция
clear
гарантирует, что после выполнения вызова
cin.clear
поток
cin
перейдет в состояние
good
.

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

*
или признаком конца файла (<Ctrl+Z> в системе Windows или <Ctrl+D> в системе Unix). Например, пусть в файле записаны следующие числа:

1 2 3 4 5 *

Ввести их можно с помощью такой функции:

void fill_vector(istream& ist, vector<int>& v, char terminator)

// считывает целые числа из потока ist в вектор v,

// пока не будет достигнут признак eof или символ завершения

{

int i = 0;

while (ist >> i) v.push_back(i);

if (ist.eof) return; // отлично: мы достигли конца файла

if (ist.bad) error("Поток ist поврежден."); // поток поврежден;

// стоп!

if (ist.fail) { // очищаем путаницу как можем и сообщаем

Поделиться:
Популярные книги

Сердце Дракона. Том 19. Часть 1

Клеванский Кирилл Сергеевич
19. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.52
рейтинг книги
Сердце Дракона. Том 19. Часть 1

Последняя Арена 10

Греков Сергей
10. Последняя Арена
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Последняя Арена 10

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21

Звезда сомнительного счастья

Шах Ольга
Фантастика:
фэнтези
6.00
рейтинг книги
Звезда сомнительного счастья

Live-rpg. эволюция-4

Кронос Александр
4. Эволюция. Live-RPG
Фантастика:
боевая фантастика
7.92
рейтинг книги
Live-rpg. эволюция-4

Девятое правило дворянина

Герда Александр
9. Истинный дворянин
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Девятое правило дворянина

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу

Para bellum

Ланцов Михаил Алексеевич
4. Фрунзе
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Para bellum

Егерь

Астахов Евгений Евгеньевич
1. Сопряжение
Фантастика:
боевая фантастика
попаданцы
рпг
7.00
рейтинг книги
Егерь

Вечная Война. Книга VII

Винокуров Юрий
7. Вечная Война
Фантастика:
юмористическая фантастика
космическая фантастика
5.75
рейтинг книги
Вечная Война. Книга VII

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

Ваантан

Кораблев Родион
10. Другая сторона
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Ваантан

Идущий в тени 4

Амврелий Марк
4. Идущий в тени
Фантастика:
боевая фантастика
6.58
рейтинг книги
Идущий в тени 4

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник