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

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

Жанры

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

int h;

double t;

is >> d >> h >> t >> ch2;

if (!is || ch2!=')') error("Плохая запись"); // перепутанные

// показания

r.day = d;

r.hour = h;

r.temperature = t;

return is;

}

В принципе мы проверяем, правильно ли начинается формат. Если нет, то переводим файл в состояние

fail
и выходим. Это позволяет нам
попытаться считать информацию как-то иначе. С другой стороны, если ошибка формата обнаруживается после считывания данных и нет реальных шансов на возобновление работы, то вызываем функцию
error
.

Операции ввода в классе

Month
почти такие же, за исключением того, что в нем вводится произвольное количество объектов класса
Reading
, а не фиксированный набор значений (как делает оператор
>>
в классе
Reading
).

istream& operator>>(istream& is, Month& m)

// считываем объект класса Month из потока is в объект m

// формат: { month feb... }

{

char ch = 0;

if (is >> ch && ch!='{') {

is.unget;

is.clear(ios_base::failbit); // ошибка при вводе Month

return is;

}

string month_marker;

string mm;

is >> month_marker >> mm;

if (!is || month_marker!="month") error("Неверное начало Month");

m.month = month_to_int(mm);

Reading r;

int duplicates = 0;

int invalids = 0;

while (is >> r) {

if (is_valid(r)) {

if (m.day[r.day].hour[r.hour] != not_a_reading)

++duplicates;

m.day[r.day].hour[r.hour] = r.temperature;

}

else

++invalids;

}

if (invalids) error("Неверные показания в Month", invalids);

if (duplicates) error("Повторяющиеся показания в Month",
duplicates);

end_of_loop(is,'}',"Неправильный конец Month");

return is;

}

Позднее мы еще вернемся к функции

month_to_int;
она преобразовывает символические обозначения месяцев, такие как
jun
, в число из диапазона
[0:11]
. Обратите внимание на использование функции
end_of_loop
из раздела 10.10 для проверки признака завершения ввода. Мы подсчитываем количество неправильных и повторяющихся объектов класса
Readings
(эта информация может кому-нибудь понадобиться).

Оператор

>>
в классе
Month
выполняет грубую проверку корректности объекта класса
Reading
, прежде чем записать его в память.

const int implausible_min = –200;

const int implausible_max = 200;

bool is_valid(const Reading& r)

//
грубая проверка

{

if (r.day<1 || 31<r.day) return false;

if (r.hour<0 || 23<r.hour) return false;

if (r.temperature<implausible_min ||
implausible_max<r.temperature)

return false;

return true;

}

В заключение можем прочитать объекты класса

Year
. Оператор
>>
в классе
Year
аналогичен оператору
>>
в классе
Month
.

istream& operator>>(istream& is, Year& y)

// считывает объект класса Year из потока is в объект y

// формат: { year 1972... }

{

char ch;

is >> ch;

if (ch!='{') {

is.unget;

is.clear(ios::failbit);

return is;

}

string year_marker;

int yy;

is >> year_marker >> yy;

if (!is || year_marker!="year")

error("Неправильное начало Year");

y.year = yy;

while(true) {

Month m; // каждый раз создаем новый объект m

if(!(is >> m)) break;

y.month[m.month] = m;

}

end_of_loop(is,'}',"Неправильный конец Year");

return is;

}

Можно было бы сказать, что этот оператор “удручающе аналогичен”, а не просто аналогичен, но здесь кроется важный нюанс. Посмотрите на цикл чтения. Ожидали ли вы чего-нибудь подобного следующему фрагменту?

Month m;

while (is >> m)

y.month[m.month] = m;

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

operator>>(istream& is, Month& m)
не присваивает объекту m совершенно новое значение; она просто добавляет в него данные из объектов класса
Reading
. Таким образом, повторяющаяся инструкция
is>>m
добавляла бы данные в один и тот же объект
m
. К сожалению, в этом случае каждый новый объект класса
Month
содержал бы все показания всех предшествующих месяцев текущего года. Для того чтобы считывать данные с помощью инструкции
is>>m
, нам нужен совершенно новый объект класса
Month
. Проще всего поместить определение объекта m в цикл так, чтобы он инициализировался на каждой итерации.

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

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Предатель. Вернуть любимую

Дали Мила
4. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Предатель. Вернуть любимую

Бывший муж

Рузанова Ольга
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Бывший муж

Мама для дракончика или Жена к вылуплению

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мама для дракончика или Жена к вылуплению

Жандарм 5

Семин Никита
5. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 5

Менталист. Эмансипация

Еслер Андрей
1. Выиграть у времени
Фантастика:
альтернативная история
7.52
рейтинг книги
Менталист. Эмансипация

Кодекс Охотника. Книга XXIV

Винокуров Юрий
24. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXIV

Лорд Системы 14

Токсик Саша
14. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 14

Смерть может танцевать 4

Вальтер Макс
4. Безликий
Фантастика:
боевая фантастика
5.85
рейтинг книги
Смерть может танцевать 4

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

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

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Не отпускаю

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
8.44
рейтинг книги
Не отпускаю

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

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

Темный Патриарх Светлого Рода 3

Лисицин Евгений
3. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 3