KnigkinDom.org» » »📕 Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп

Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!

1 ... 110 111 112 113 114 115 116 117 118 ... 337
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

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

// где-то: пусть поток ist генерирует исключение при сбое

ist.exceptions(ist.exceptions()|ios_base::badbit);

void end_of_loop(istream& ist, char term, const string& message)

{

  if (ist.fail()) { // используем символ завершения ввода

                    // и/или разделитель

    ist.clear();

    char ch;

    if (ist>>ch && ch==term) return; // все хорошо

    error(message);

  }

}

Это позволяет нам сократить цикл ввода.

My_type var;

while (ist>>var) { // читаем до конца файла

  // тут можно было бы проверить, является ли переменная var

  // корректной

  // тут мы что-нибудь делаем с переменной var

}

end_of_loop(ist,'|'," неправильное завершение файла "); // проверяем,

                                                        // можно ли

                                                        // продолжать

// продолжаем: обнаружен конец файла или признак завершения ввода

Функция end_of_loop() не выполняет никаких действий, кроме проверки, находится ли поток в состоянии fail(). Мы считаем, что эту достаточно простую и универсальную функцию можно использовать для разных целей.

10.11. Чтение структурированного файла

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

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

• Запись о годе начинается символами { year, за которыми следует целое число, обозначающее год, например 1900, и заканчивается символом }.

• Год состоит из месяцев, в течение которых производились измерения.

• Запись о месяце начинается символами { month, за которыми следует трехбуквенное название месяца, например jan, и заканчивается символом }.

• Данные содержат показания времени и температуры.

• Показания начинаются с символа (, за которыми следует день месяца, час дня и температура, и заканчиваются символом ).

{ year 1990 }

{year 1991 { month jun }}

{ year 1992 { month jan ( 1 0 61.5) } {month feb (1 1 64) (2 2 65.2)}}

{year 2000

{ month feb (1 1 68 ) (2 3 66.66 ) ( 1 0 67.2)}

{month dec (15 15 –9.2 ) (15 14 –8.8) (14 0 –2) }

 

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

Предположим, данные о температуре записаны в указанном выше формате и нам нужно их прочитать. К счастью, формат содержит автоматически идентифицируемые компоненты, такие как годы и месяцы (немного напоминает форматы HTML и XML). С другой стороны, формат отдельной записи довольно неудобен. Например, в ней нет информации, которая могла бы нам помочь, если бы кто-то перепутал день месяца с часом или представил температуру по шкале Цельсия, хотя нужно было по шкале Фаренгейта, и наоборот. Все эти проблемы нужно как-то решать. 

10.11.1. Представление в памяти

 Как представить эти данные в памяти? На первый взгляд, необходимо создать три класса, Year, Month и Reading, точно соответствующие входной информации. Классы Year и Month очевидным образом могли бы оказаться полезными при обработке данных; мы хотим сравнивать температуры разных лет, вычислять среднемесячные температуры, сравнивать разные месяцы одного года, одинаковые месяцы разных лет, показания температуры с записями о солнечном излучении и влажности и т.д. В принципе классы Year и Month точно отображают наши представления о температуре и погоде: класс Month содержит ежемесячную информацию, а класс Year — ежегодную. А как насчет класса Reading ? Это понятие низкого уровня, связанное с частью аппаратного обеспечения (сенсором). Данные в классе Reading (день месяца, час и температура) являются случайными и имеют смысл только в рамках класса Month. Кроме того, они не структурированы: никто не обещал, что данные будут записаны по дням или по часам. В общем, для того чтобы сделать с данными что-то полезное, сначала их необходимо упорядочить. Для представления данных о температуре в памяти сделаем следующие предположения.

• Если есть показания для какого-то месяца, то их обычно бывает много.

• Если есть показания для какого-то дня, то их обычно бывает много.

В этом случае целесообразно представить класс Year как вектор, состоящий из 12 объектов класса Month, класс Month — как вектор, состоящий из 30 объектов класса Day, а класс Day — как 24 показания температуры (по одному в час). Это позволяет просто и легко манипулировать данными при решении самых разных задач. Итак, классы Day, Month и Year — это простые структуры данных, каждая из которых имеет конструктор. Поскольку мы планируем создавать объекты классов Month и Day как часть объектов класса Year еще до того, как узнаем, какие показания температуры у нас есть, то должны сформулировать, что означает “пропущены данные” для часа дня, до считывания которых еще не подошла очередь.

const int not_a_reading = –7777; // ниже абсолютного нуля

Аналогично, мы заметили, что часто в течение некоторых месяцев не производилось ни одного измерения, поэтому ввели понятие “пропущен месяц”, вместо того чтобы проверять пропуски для каждого дня.

const int not_a_month = –1;

Три основных класса принимают следующий вид:

struct Day {

  vector<double> hour;

  Day(); // инициализируем массив hour значениями "нет данных"

};

Day::Day()

    : hour(24)

{

  for (int i = 0; i<hour.size(); ++i) hour[i]=not_a_reading;

}

struct Month

1 ... 110 111 112 113 114 115 116 117 118 ... 337
Перейти на страницу:
Отзывы - 0

Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.


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

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.


Партнер

Новые отзывы

  1. Гость Татьяна Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
  2. Римма Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
  3. Римма Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова
Все комметарии
Новое в блоге