Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Sitkin_Informatika_Programmirovanie_v_DELPHI.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
600.56 Кб
Скачать

Пример 10.2

Разработаем проект для считывания чисел прямоугольной мат-рицыизвнешнего файлавсоответствующийдвумерныймассив.

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

Дляреализациивозможностивыборафайлапользователем,скоторогобудутсчитыватьсяданные,обеспечимзагрузкуокнаоткры-тияфайла,разместивнаформекомпонентOpenDialog.Установимвоз-можность выбора только текстовых файлов, создав фильтр (рис. 10.1).Еслифайлнебудетвыбранпользователемилибудетвыбран,ноока-жетсянедоступным(ошибкаоткрытия),предусмотримдосрочноеза-вершениеработысвыдачейсоответствующегосообщения(рис.10.2).Еслифайлоткрыт,иперваяжепозицияуказателячтенияокажетсяипоследней(т.е.сразудостигнутконецфайла),проинформируемполь-зователяоботсутствииданныхитакжедосрочнозавершимработу.Послетройнойпроверки,вслучаеуспешногоеёпрохождения,

переходимнепосредственнокобработкесодержимогофайла.

начало

файлвыбран

да

нет

файлневыбран

ошибка да

открытия

нет

конец да

файла

нет

переводстроки

файлненайден

файлпустой

выделитьпамятьmn

закрытьфайл

1

2

закрытьфайл

ошибкасинтаксиса

переоткрытьфайл

нет

n=n+1

нет

конецфайла

да

переводпоз.чтениявстроке

конецстроки

переоткрытьфайл

да

im1

да

jn1

давводxijизфайла

ошибкавводаxij

j=j+1

нет

нет

i=i+1

номерстолб-цаj=0

закрытьфайл

нет

да2

конец

1 Рис.10.2

Переводя в цикле указатель чтения по строкам и считая количе-ство раз перевода строки, пока не достигнем конца файла, определимчислоmэтих строк. Чтобы вернуть указатель чтения в начало первойстроки (в начало файла), повторно откроем файл. Во втором цикле,переводя указатель чтения по элементам первой строки, пока не будетдостигнут её конец, аналогично определим числоnстолбцов. Зная те-перь размеры матрицы, выделим память под массив размеромmn.Вновь вернув указатель чтения в начало файла (к первому элементуматрицы), начнём считывание элементов из файла по одному, после-довательно продвигаясь по строкам и столбцам. Для этого применимзнакомуюконструкциювложенныхциклов.Предусмотримпро-граммный контроль ввода текущего элемента в память, отключив ав-томатическуюобработкуошибокввода/выводапередпроцедуройсчитывания текущего элемента из файла, затем восстановим её. Еслипопытка считать текущий элемент окажется неудачной, то проинфор-мируем пользователя о недопустимом элементе в файле (символ илистрока символов, которые не могут быть интерпретированы как веще-ственное число), закроем файл, завершив его обработку досрочно. Ес-ли же ни в одном элементе не будет синтаксических ошибок, то всечисла будут считаны в память, произойдёт штатный выход из телавнешнего цикла, после чего файл следует закрыть. Ниже представлентекстпроцедуры,реализующейразработанныйалгоритмрис.10.2.

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

IMPLEMENTATION

{$R*.dfm}

varx:arrayofarrayofreal;//объявленкакглобальныйдинамич.массив

procedureTForm1.Button1Click(Sender:TObject);

varf:textfile; i,j,m, n:byte;z:real;

BEGIN

IfOpenDialog1.ExecuteThen//еслифайлвыбранпользователемвокне

Begin

AssignFile(f,OpenDialog1.FileName);//связатьегоспеременнойf

{$I-}Reset(f);{$I+}//открытьфайл,связанныйсfдлячтения

ifIOResult <>0then beginShowMessage('Файл не найден'); Exit;end;End

ElseBeginShowMessage('Файлневыбран');Exit;End;

ifeof(f)thenbeginShowMessage('Файлпустой');CloseFile(f);Exit;end;

m:=0;n:=0;//начальныезначениясчётчиковстрокистолбцов

repeat//циклподсчётачисластрок

Readln(f);//переводуказателячтения вфайлеfнаследующуюстроку

m:=m+1;//увеличениезначениясчётчикастрокна единицу

untileof(f);//выходизцикла,еслидостигнутконецфайлаReset(f);//повторн. откр-е файла для возврата указателя чтения в начало файлаrepeat//циклподсчётачисла элементовпервойстроки(числастолбцов)

{$I-}Read(f,z);{$I+}//безzнебудетпереводауказателя чтениякслед-щей

//позиции, поэтому контролируем, допустимое ли число записывается вzifIOResult <>0then//если ошибка синтаксиса элемента в 1-ой строкеbeginShowMessage('Ошибка в 1-ой строке'); CloseFile(f); Exit;end;n:=n+1;//увеличениезначениясчётчикастолбцовнаединицу

untileoln(f); //выход из цикла, если достигнут конец строкиReset(f);//повторн. откр-е файла для возврата указателя чтения в начало файлаSetLength(x,m,n);//выделениепамятиподдвумерныймассив(матрицу)fori:=0tom1do//внешний цикл (в нём один оператор – вложенный for)forj:=0ton1do Begin//началотелавложенногоцикла

{$I-}Read(f,x[i,j]);{$I+}//вводxijэлементаизфайлаifIOResult <>0then//если ошибка синтаксиса эл-нтаbegin

ShowMessage('Ошибка синтаксиса эл-нта в файле');CloseFile(f);SetLength(x,0,0);Exit;

end;

End;//конецтелавложенногоцикла

CloseFile(f);//закрытиефайлачтения

END;//конецпроцедуры