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

Пример 10.3

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

Как и в предыдущем проекте, предусмотрим загрузку окна от-крытия файла и контроль выбора файла, его доступности и наличияданных в нём (рис. 10.3). В случае успешного его прохождения, ис-пользуя конструкцию вложенных циклов, поэтапно будем выделятьпамять. В теле внешнего цикла на каждой итерации – под двумерныймассивxсначала по первому измерению для одной строки и под одинэлементодномерногомассиваy,вкоторыйпотомзапишемдлину(число элементов) этой строки. В теле вложенного цикла на первойитерации выделяется, а со второй – добавляется память по второмуизмерению под один элемент текущей строки двумерного массива. Вэту ячейку памяти записывается текущий элемент из файла, если нетошибки синтаксиса, и т.д. для всех элементов строки. По окончаниистроки происходит выход из вложенного цикла, в одномерный массивyзаписывается длина только что пройденной строки (число итерацийвнутреннего цикла на данной строке), указатель чтения переходит кследующейстроке,ивсёповторяется, покафайлнезакончится.

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

начало

файлвыбран

открытьфайлчтения

да

ошибкаоткрытия

нет

конецфайла

номерстроки

i= 0

нет

нет

да

да

файлчтения

невыбран

файлчтения

ненайден

файлчтения

пустой

1

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

закрытьфайлчтения

высвободитьвсюпамять

нет

не конецфайла

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

выд-тьпамятьподi-уюстр.

да

закрытьфайлчтения

закрыть файлчтения. числострокm=i

файлвыбран

открытьфайлзаписи

да

ошибкадоступа

нет

нет

да

файлзаписи

невыбран

файл записинедоступен

неконец

строки

закрыть файлзаписи. высв-тьвсюпамять

да

нет

im1

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

да

нет

выд-тьпамятьподj-ый эл-тi-ойстроки

длинаi-ойстрокиyi=j

конец

вводxij

изфайла

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

j=j+1

нет

да 1

i=i+ 1

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

jyi1

да

записьx2ij

вфайл

нет

i=i+1

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

j=j+ 1

Рис.10.3

varf1,f2:textfile;i,j,m:byte;x:arrayofarrayofreal;y:arrayofbyte;

BEGIN

IfOpenDialog1.ExecuteThen//еслифайлвыбранвокнеоткрытияфайла

Begin

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

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

ifIOresult <>0thenbeginShowMessage('Файл не найден'); Exit;end;End

ElseBeginShowMessage('файлдлячтенияневыбран');Exit;End;

ifeof(f1)thenbeginShowMessage('файлпуст');Closefile(f1);Exit;end;

i:=0;//начальноезначениеномерастроки

whilenoteof(f1)do//поканедостигнутконецфайла

Begin//началотелавнешнегоцикла

SetLength(x, i+1); //выделение (добавл.) памяти под одну строку массиваxSetLength(y, i+1); //выделение (добавл.) памяти под один элемент массиваyj:=0;//начальноезначениеномерастолбца(номераэлементавстроке)

whilenoteoln(f1)do//поканедостигнутконецстроки

begin //началотелавложенногоцикла

SetLength(x[i],j+1);//выделениепамятипододинэл-нтвi-ойстроке

{$I-}Read(f1,x[i,j]);{$I+}//чтение(ввод)xijэлементаиз файла

ifIOResult<>0thenbegin

ShowMessage('Ошибка син-са'); CloseFile(f1);SetLength(x,0,0);SetLength(y,0); Exit;

end;

j:=j+1;//переходкследующемустолбцувi-ойстроке

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

y[i]:=j;//записьвмассивyдлиныi-ойстроки

i:=i+1;//переходкследующейстроке

Readln(f1);//переводстрокичтениявфайлечтения

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

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

m:=i; //число строк получает значение числа итераций внешнего циклаIfSaveDialog1.ExecuteThen//если файл выбран в окне сохраненияBegin

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

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

ifIOResult <>0then beginShowMessage('Ошибка доступа'); Exit;end;End

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

i:=0;//начальноезначениеномерастроки

whilei<=m-1do//поканеисчерпанывсестроки

Begin//началотелавнешнегоцикла

j:=0; //начальное значение номера столбца (номера элемента в строке)whilej <= y[i]-1do//пока не исчерпаны все элементыi-ой строкиbegin//началотелавложенногоцикла

Write(f2,sqr(x[i,j]):5:2,'');//записьвфайл квадратаэлементав формате

j:=j+1;//переходкследующемустолбцу 5:2спробелом

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

i:=i+1; //переход к следующей строке выводаWriteln(f2); //перевод строки записи в файлеEnd;//конец тела внешнего циклаCloseFile(f2);//закрытиефайлазаписи

SetLength(x, 0, 0); //высвоб. памяти из-под двумерного массива элементовSetLength(y, 0); //высвоб. памяти из-под одномерного массива длин строкEND;//конец процедуры

Нарис.10.4представленрезультатработыприложения.

Рис.10.4

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