ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 12) онлайн

Упражнения

Решения к упражнениям, помеченным знаком *, можно найти в приложении Ж. *1. Рассмотрите класс Distance из программы ENGLCON, глава 6 «Объекты и                 классы». Используя цикл, аналогичный приводимому в программе DISKFUN                 в этой главе, получите несколько значений от пользователя и запишите                 их в файл. Добавьте их к уже записанным там данным (при их наличии).                 При окончании пользователем ввода прочитайте файл и выведите на эк-                 ран все значения.

*2. Напишите программу, эмулирующую команду COPY (MS DOS). То есть программа должна копировать содержимое одного файла в другой. Долж- но использоваться два аргумента командной строки — исходный файл и файл назначения. Например:

                С:\>оcopy srcfile.cpp destfile.cpp

Осуществляйте проверку числа аргументов командной строки и возмож- ность открытия указанных пользователем файлов.

*3. Напишите программу, возвращающую размер файла, указанного в команд- ной строке:

                C:\>filesize program.ext.

4. В цикле запрашивайте у пользователя данные, состоящие из имени, отчест- ва, фамилии и номера работника (типа unsigned long). Затем осуществите форматированный вывод в объект ofstream с помощью оператора вставки (<<). Не забывайте, что строки данных должны оканчиваться пробелами или другими разделителями. Когда пользователь сообщит об окончании ввода, закройте объект ofstream, откройте объект ifstream, прочитайте и вы- ведите на экран все данные из файла, после чего завершите программу.

5. Создайте класс time, включающий себя целые значения часов, минут и се- кунд. Напишите метод get_time(), спрашивающий время у пользователя, и метод put_time(), выводящий время в формате 12:59:59. Внесите в функ- цию get_time() проверку на ошибки, чтобы минимизировать возможность неправильного ввода пользователем. Эта функция должна отдельно спра- шивать часы, минуты и секунды, проверяя каждое введенное значение на наличие флагов ошибок ios, а также проверяя, укладывается ли значение в заданный диапазон. Для часов диапазон составляет от 0 до 23, а для ми- нут и секунд — от 0 до 59. Не вводите данные в виде символьных строк с последующим конвертированием. Вводите значения сразу же как int. Это означает, что вы не сможете выявлять записи с ненужными здесь деся- тичными запятыми, но это в данной программе не так важно.

В main() используйте цикл для получения значений времени от пользова- теля функцией get_time(), затем для их вывода функцией put_time();

Введите часы: 8 Введите минуты: 2 Введите секунды: 39 Время= 8:02:39 Продолжить (y/n)? у Введите часы: 28

Значение часов должно лежать между 0 и 23!

Введите часы: 1

Введите минуты: 10

Введите секунды: пять

Неправильно введены секунды!

Введите секунды: 5

Время = 1:10:05

6. Создайте класс name, включающий в себя данные из упражнения 4 (имя, отчество, фамилия и номер работника). Создайте методы для этого класса,

осуществляющие файловый ввод/вывод данных указанного класса (с ис- пользованием ofstream и ifstream). Используйте форматирование данных (операторы << и >>). Функции чтения и записи должны быть независи- мыми: в них необходимо внести выражения для открытия соответству- ющего потока, а также чтения и записи данных.

Функция записи может просто добавлять данные в конец файла, Функ- ции чтения потребуется некоторое условие выборки конкретной записи. Можно вызывать ее с параметром, представляющим собой номер записи. Но как, даже зная, какую запись следует читать, функция найдет ее? Ис- пользование seekg() тут не поможет, так как при форматированном вво- де/выводе все записи имеют разные размеры (в зависимости от количества символов в строке и разрядности числа). Поэтому придется просто счи- тывать записи подряд, пока не будет найдена нужная.

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

7. Другим подходом к добавлению файлового потока к объекту является превращение самого этого потока в статическую компоненту объекта. Для чего это делается? Ну, часто бывает проще представить себе поток свя- занным с классом в целом, а не с отдельными его объектами. К тому же, гораздо правильнее открывать поток только один раз для записи и чтения всего, что нужно. Например, мы открываем файл и начинаем последова- тельное чтение. Функция чтения всякий раз возвращает данные для сле- дующего объекта. Указатель файла сдвигается при этом автоматически, так как между чтениями файл мы не закрываем.

Перепишите программы из упражнений 4 и 6 таким образом, чтобы ис- пользовать объект fstream в качестве статической компоненты класса name. Функционирование программы должно сохраниться. Напишите статиче- скую функцию для открытия потока и еще одну — для сбрасывания фай- лового указателя и установки его на начало файла. Эту же функцию мож- но использовать для чтения всего файла.

8. Основываясь на программе LINKLIST из главы 10 «Указатели», напиши- те программу, позволяющую пользователю выбрать одно из четырех дей- ствий нажатием соответствующей кнопки. Действия таковы:

добавить ссылку в список (от пользователя требуется ввести целое число)

показать данные по всем ссылкам из списка;

записать в файл данные для всех ссылок (создание или переписывание файла);

считать все данные из файла и создать новый список ссылок, куда и по- местить их.

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

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

9. Начните с упражнения 7 главы 8 «Перегрузка операций» и перегрузите операторы извлечения (>>) и вставки (<<) для класса frac в нашем кальку- ляторе с четырьмя действиями. Имейте в виду, что операторы могут свя- зываться в цепочки, поэтому при выполнении действий с дробями пона- добится только одно выражение; cin >>frac1>> op >> frac2;

10. Добавьте к упражнению 9 проверку на наличие ошибок в операторе из- влечения (>>), Но при этом, видимо, потребуется запрашивать сначала первую дробь, затем оператор, затем вторую дробь. Одним выражением, как в упражнении 9, уже будет не обойтись. Вывод сообщений об ошиб- ках сделает работу с программой более понятной.

Введите первую дробь: 5/0 Знаменатель не может быть нулевым! Введите первую дробь заново: 5/1 Введите оператор (+,-, *,/): + Введите вторую дробь: одна треть Ошибка ввода

Введите вторую дробь заново: 1/3

Ответ:  16/3

Продолжить (y/n)? n

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

11. Начните с класса bMoney, который мы последний раз видели в упражне- нии 5 главы 11. Перегрузите операторы извлечения и вставки, чтобы мож- но было осуществлять ввод/вывод объектов этого класса. Выполните ка- кой-нибудь ввод/вывод в main().

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

ПРИМЕЧАНИЕ               

Не пытайтесь прочитать файл, созданный программой EMPL_IO. Классы в программах раз- ные благодаря методу find() в новой программе, и проблемы, которые могут возникнуть в случае, если их данные смешаются, уже обсуждались в этой главе. Вам может понадо- биться включить параметр RTTI в компиляторе. Чтобы не возникало вопросов, следуйте указаниям, данным в приложении В «Microsoft Visual C++» и в приложении Г «Borland C++ Builder» (выбирайте то, что для вас актуальней).

 

 

48