- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
struct Reading { // данные о температуре воздуха
int hour; // часы после полуночи [0:23]
double temperature; // по Фаренгейту
Reading(int h, double t) :hour(h), temperature(t) { }
};
В таком случае данные можно считать следующим образом:
vector<Reading> temps; // здесь хранится считанная информация
int hour;
double temperature;
while (ist >> hour >> temperature) {
if (hour < 0 || 23 <hour) error("Некорректное время");
temps.push_back(Reading(hour,temperature));
}
Это типичный цикл ввода. Поток istream с именем ist мог бы быть файловым потоком ввода (ifstream), как в предыдущем разделе, стандартным потоком ввода (cin) или любым другим потоком istream. Для кода, подобного приведенному выше, не имеет значения, откуда поток istream получает данные. Все, что требуется знать нашей программе, — это то, что поток ist относится к классу istream и что данные имеют ожидаемый формат. Следующий раздел посвящен интересному вопросу: как выявлять ошибки в наборе входных данных и что можно сделать после выявления ошибки форматирования.
Записать данные в файл обычно проще, чем считать их оттуда. Как и прежде, как только поток проинициализирован, мы не обязаны знать, что именно он собой представляет. В частности, мы можем использовать выходной файловый поток (ofstream) из предыдущего раздела наравне с любым другим потоком ostream.
Например, мы могли бы пожелать, чтобы на выходе каждая пара была заключена в скобки.
for (int i=0; i<temps.size(); ++i)
ost << '(' << temps[i].hour << ',' << temps[i].temperature << ")n";
Затем итоговая программа прочитала бы исходные данные из файла и создала новый файл в формате (час, температура).
Поскольку файловые потоки автоматически закрывают свои файлы при выходе из области видимости, полная программ принимает следующий вид:
#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

