Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab03_2010

.pdf
Скачиваний:
29
Добавлен:
07.06.2015
Размер:
1.72 Mб
Скачать

Лабораторная работа 3. Двумерные массивы. Файловый ввод / вывод

В лабораторной работе 2 ввод данных осуществлялся с клавиатуры, а вывод на экран. Это далеко не всегда удобно, особенно если объем данных достаточно велик, а вводить его (хотя бы даже в целях отладки) приходится неоднократно. Кроме того, данные могут быть получены из другой программы или из каких-то иных источников. Поэтому в настоящей лабораторной работе наряду с двумерными массивами будет изучен также ввод и вывод в файлы (умение работать с файлами будет одним из необходимых условий для сдачи зачета по языкам программирования).

Проект № 3. Работа с двумерным массивом

Приложение, которое мы сейчас разработаем, будет решать следующую задачу. Задан двумерный массив вещественных чисел размером n × m (n >1, m > 1).

а) Найти сумму максимальных элементов его строк б) Получить массив, состоящий из минимальных элементов его столбцов

в) Найти в массиве элементы, равные заданному числу, с точностью до некоторого ε. Указать их координаты (если хотя бы один такой есть) или же сообщить об отсутствии таких элементов.

г) Назовем соседями элемента по столбцу элемент, находящийся выше него, и элемент, находящийся ниже него. Назовем соседями элемента по строке элемент, находящийся левее него, и элемент, находящийся правее него. Разумеется, если элемент находится, например, в левом верхнем углу, у него есть только один сосед по столбцу и один сосед по строке. Если выполняется одно из двух условий:

элемент меньше всех (т.е. двух или одного) своих соседей по столбцу и больше всех своих соседей по строке

или же элемент больше всех своих соседей по столбцу и меньше всех своих соседей по строке,

заменить его суммой всех его соседей.

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

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

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

Ввод данных в приложение будет осуществляться из файла, вывод – в файлы же.

Создайте новый проект вида Java Application, назовите его lab03_gp, а его главный класс – WorkWithMatrix (работа с матрицей) и сохраните в папке

W:\JavaProjects\LR03_01). Все остальные настройки при создании проекта менять не нужно. У Вас должно получиться следующее:

Рис. 1. NetBeans после создания нового проекта

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

Чтобы закрыть проект, нужно щелкнуть на его имени правой клавишей мыши и в контекстном меню выбрать Close (рис. 2).

Закройте все проекты, кроме последнего созданного (lab03_gp). Обратите внимание, что с закрытием проекта из основного окна NetBeans

исчезают вкладки с соответствующими

Рис. 2. Закрытие проекта

им файлами с расширением java.

2

§ 1. Создание файла с входными данными

Как и в предыдущем проекте, главный класс (WorkWithMatrix) будет использован лишь для запуска программы. Методы, решающие поставленные задачи, будут содержаться в другом классе, который мы назовем Matrix. Создайте такой класс и опишите в нем следующие поля: двумерный массив вещественных чисел array, а также целочисленные поля n и m (количества строк и столбцов в массиве соответственно) (рис. 3).

Рис. 3. Класс Matrix и объявленные в нем поля

Формирование массива, как и раньше, выполним в конструкторе. Однако, поскольку мы бы хотели прочитать данные из файла, необходимо определиться, что и как в этом файле будет записано.

Вполне естественным представлением исходных данных можно считать, например, такое: в первой строке входного файла через пробел записаны числа n и m, а затем каждая из n строк содержит по m вещественных чисел – элементов массива. Создадим такой файл в проекте и назовем его input.txt.

Чтобы создать файл, можно воспользоваться либо главным меню File | New File (рис. 4А),

Рис. 4A. Создание нового файла с помощью главного меню

либо контекстным меню проекта New | Other (рис. 4B), после чего появится диалоговое окно New File (Choose File Type), где следует выбрать категорию Other и пункт Empty File (рис. 5).

3

Рис. 4B. Создание файла из контекстного меню

Рис. 5. Первое диалоговое окно создания файла

Нажав Next и переключившись к следующему диалоговому окну New File (Name and Location), Вы сможете указать имя создаваемого файла (строка File Name) – input.txt и его местоположение (рис. 6). По умолчанию вновь создаваемый файл помещается в папку проекта (lab03_gp в нашем случае). Такое размещение позволяет обращаться из программы к файлу просто по имени, без указания пути. Поэтому изменять его не будем (при необходимости можно воспользоваться кнопкой Browse и указать нужную папку в диалоговом окне выбора папки).

4

Рис. 6. Имя нового файла и его местоположение

После завершения работы с диалоговым окном в главном окне появится еще одна вкладка с именем input.txt (рис. 7).

Рис. 7. Новый пустой файл input.tx

Теперь можно заполнить файл данными, которые мы будем использовать в качестве тестового примера. Будем считать, что в массиве будет 5 строк, 6 столбцов. Значения элементов массива в нем подобраны таким образом, чтобы выполнение заданий пунктов в) и г) не было тривиальным (т.е. чтобы элементы, удовлетворяющие описанным в задаче условиям, существовали, и не в единственном числе). Поэтому перепечатайте эти числа в точности, как на рис. 8.

Выравнивание по десятичной точке соблюдать необязательно – достаточно, чтобы числа были отделены друг от друга хотя бы одним пробелом (а внутри чисел пробелов бы не содержалось). Но с точки зрения человека такой вид удобнее для восприятия.

5

Рис. 8. Файл с двумерным массивом

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

§ 2. Чтение данных из файла

Переключитесь на вкладку WorkWithMatrix.java. Наша следующая задача – разработка конструктора, который прочитает данные из входного файла и поместит их в массив array. Чтение из файла организуем с помощью объекта класса Scanner, который будет создан не на основе стандартного потока ввода System.in, а на основе файла input.txt. Однако непосредственно имя файла передать в качестве параметра конструктору класса Scanner нельзя, он должен получить либо объект, поддерживающий интерфейс Readable, либо объект класса File. Применим первый подход и, описав конструктор, объявим в нем переменную fin (сокращение от file input) класса FileReader (поддерживающего интерфейс Readable), получим уже знакомое сообщение об ошибке

(рис. 9).

Рис. 9. Опишем конструктор и объект fin класса

FileReader в нем

Добавьте объявление импорта класса java.io.FileReader (c помощью контекстного меню, появляющегося при щелчке мышкой на «лампочке»). Других исправлений пока не вносите (останется сообщение о том, что не хватает точки с запятой в конце объявления). Допечатайте объявление до конца, как показано на рис. 10. Обратите внимание, что предупреждение об ошибке не исчезло. Если Вы наведете курсор мыши на «лампочку», то прочитаете сообщение о том, что исключение java.io.FileNotFoundException должно быть либо обработано, либо пропущено (рис. 11).

6

Рис. 10. После завершения описания переменной предупреждение об ошибке не исчезло

Рис. 11. Исключение должно быть обработано или объявлено как пропускаемое

Причины такого поведения системы понятны: в отличие от стандартного потока ввода, который существует всегда (и независимо от нас), файл может отсутствовать. Именно в такой ситуации и возникает исключение FileNotFoundException («файл не найден»). Одно из возможных поведений приложения в этом случае – предложить пользователю указать, где находится искомый файл.

Пока мы будем предполагать, что файл наверняка существует и находится именно там, где его ожидает «увидеть» приложение (а если это почему-либо не так, то пользователь сразу же догадается, что нужно делать). Поэтому обсуждение того, как написать обработку исключения, отложим до одной из следующих лабораторных работ, а сейчас укажем в заголовке конструктора, что он пропускает исключение FileNotFoundException. Заметим, что слово «пропускает» должно истолковываться практически буквально – как пропуск на более высокий уровень, конкретно – на уровень метода, в котором конструктор класса Matrix будет вызван. Ответственность за какуюлибо обработку исключения будет возложена уже на него. Разумеется, и этот метод может передать ответственность дальше, также пропустив это исключение. Самый высокий уровень – это уровень JVM, виртуальной машины Java, в которой существуют предопределенные обработчики исключений (в нашем случае будет выдано сообщение о том, что файл не найден).

Примечание.

Исключения все же надо обрабатывать. Конечно, когда программа предназначена для

однократного использования программистом, ее написавшим, подход с пропусканием исключений допустим.

Нажатие на «лампочку» приведет к выдаче вариантов действий, из которых надо выбрать добавление предложения throws для указанного исключения (рис. 12).

7

Рис. 12. Следует добавить предложение throws, чтобы конструктор пропускал исключение FileNotFoundException

Обратите внимание, что, кроме добавления предложения throws в заголовок конструктора Matrix() (рис. 13), произошло также добавление предложения импорта класса исключительной ситуации (рис. 14).

Рис. 13. Предложение throws добавлено

Рис. 14. Также добавлено и предложение импорта

FileNotFoundException

Теперь можно объявить переменную класса Scanner (рис. 15) и добавить предложение импорта, следуя подсказкам среды.

Рис. 15. При создании объекта scr используем fin как параметр конструктора

Все готово для чтения из файла. Последовательность действий будет такова: сначала прочитаем число строк и число столбцов (записанные в первой строке файла input.txt), затем выделим необходимую память для массива array, после чего можно будет приступать к чтению элементов массива. Обратите внимание, что в файле input.txt

8

использована точка в качестве разделителя целой и дробной части числа, поэтому необходимо будет указать, что используется локаль либо US, либо UK. Напомним, что нумерация и строк, и столбцов начинается с нуля. Код, прочитывающий размер массива, а затем его элементы, показан на рис. 16.

Рис. 16. Чтение из файла размера массива и его элементов

Однако это еще не все: по завершении работы с файлом нужно его закрыть – с помощью метода close(). Вызов этого метода в конструкторе приведет к необходимости добавить еще одно исключение к списку пропускаемых (рис. 17).

Рис. 17. Для закрытия файла необходимо добавить исключение IOException

Добавление исключения IOException (которое в данном случае должно застраховать от попытки закрыть неоткрытый файл) приведет также к пополнению предложений импорта. Конструктор примет вид, как на рис. 18.

Вообще говоря, исключений, добавленных в предложение throws, может быть сколь угодно много. Но именно в нашем случае список можно сократить, поскольку класс FileNotFoundException расширяет класс IOException и, таким образом, может быть «поглощен» классом-предком. Если бы исключения обрабатывались, а не пропускались, то рассматривать их следовало бы именно по отдельности.

9

Рис. 18. Вид конструктора Matrix() после добавления второго пропускаемого исключения

Узнать о том, что класс FileNotFoundException является дочерним по отношению к классу IOException, можно с помощью Javadoc. В лабораторной работе № 1 говорилось о возможности подключить Javadoc к NetBeans, но, вероятно, далеко не все из вас попробовали это сделать. Выберите в главном меню Tools | Java Platforms (рис. 19) и переключитесь на вкладку Javadoc в открывшемся диалоговом окне (рис. 20).

Рис. 19. Меню Tools | Java Platforms

Единственная активная кнопка Add ZIP / Folder позволяет вызвать диалоговое окно добавления папки. В локальной сети СамГУ нужная папка распакованного Javadoc находится по адресу I:\tutorial\books\comps\programming\Java\j2se-6\api. Найдите ее, добавьте и закройте окно Java Platform Manager.

Теперь Javadoc можно пользоваться. Краткое описание класса можно получить в окне Javadoc, открываемом в среде с помощью меню Window | Other | Javadoc (рис. 21).

10

Соседние файлы в предмете Программирование на Java