Решение задач. Процедуры и функции работы с файлами.
Изменение имени файла производится процедурой
rename(МуFilе, FileName);
первый аргумент которой - переменная файлового типа, а второй аргумент - строкового типа - новое имя файла, которое может быть сокращенным или полным (с указанием пути). Действие этой процедуры эквивалентно действию аналогичной процедуры DOS.
Уничтожение части файла от текущего положения до конца производится процедурой
truncate(МуFilе).
Уничтожение всего файла производится процедурой
erase(МуFilе),
действие которой эквивалентно удалению файла в операционной системе DOS.
Примечание. Физические файлы на магнитных дисках и переменные файлового типа в программе на Паскале - объекты различные. Переменные файлового типа в Паскале соответствуют не только физическим файлам, но и логическим устройствам, связанным с вводом и выводом информации. Клавиатуре и экрану дисплея соответствуют файлы со стандартными именами Input и Output.
Задание. Рассмотрите предложенный ниже текст программы. Сформулируйте решенную задачу. Создайте расширенный вариант подобной задачи. результат покажите учителю для оценки.
Program Files;
Uses
Crt;
Var
F,Fnew: file of string;
Name,NewName: string[12];
Text: string;
Ch: char;
Procedure ReadText;
Begin
repeat
write('Введите имя файла>');
readln(Name);
assign(F,Name);
reset(F);
if IOresult<>0
then
begin
writeln('Ошибка чтения');
close(F);
end;
until IOresult=0;
writeln('Содержание файла ',Name,':');
while not Eof(F) do
begin
readln(F,Tеxt);
writeln(Tеxt);
end;
close(F);
End;
Procedure EraseFile;
Begin
erase(F);
writeln('Файл удален');
End;
Procedure ReNameFile;
Begin
write('Введите новое имя файла:');
readln(NewName);
rename(F,NewName);
writeln('Файл ',Name,' переименован в файл ',NewName);
End;
Procedure CopyFile;
Begin
write('Введите имя копии файла ',Name,'>');
readln(NewName);
reset(F);
assign(Fnew,NewName);
rewrite(Fnew);
while not Eof(f) do
begin
readln(F,Text);
writeln(Fnew,Text);
end;
close(F);
close(F_new);
writeln('Файл',Name,' скопирован в файл ',NewName);
End;
Begin
ClrScr;
readTеxt;
repeat
writeln('Удаление файла (D),переименование файла(R)');
writeln('Копирование файла (C), выход из программы (Е)');
write('Введите символ нужной операции - ');
readln(ch);
case ch of
'D','d': EraseFile;
'R','r': ReNameFile;
'C','c': CopyFile;
end;
until (ch='E') or (ch='e');
read;
End.
Выберите с учителем одну из предложенных ниже задач.
- Даны два отсортированных типизированных файла (тип выбрать произвольно). Получить новый типизированный файл слиянием двух исходных в отсортированном виде. Алгоритм слияния должен предусматривать, что исходные файлы могут содержать очень большое число элементов.
- Проверить, является ли один типизированный файл частью другого. Если является, то его распечатать на принтере.
- Сделать один типизированный файл частью другого, начиная с N-ой позиции (N задает пользователь).
- Один типизированный файл вставить в другой, чередуя элементы обоих файлов. Элементы вставляемого файла начинайте вводить с конца файла.
- Сравнить содержание файлов. Количество сравниваемых файлов задает пользователь.
Приготовьте листинги решенных и проверенных учителем задач. Проверьте свои знания, ответив на ниже следующие вопросы.
Контрольные вопросы
- Что называется файлом? как его описать в программе?
- Какие действия можно производить с файлами?
- Как записать файл? Какие процедуры или функции надо применить? Как производится запись?
- Как прочитать файл? Какие процедуры или функции используются? Как происходит чтение данных из файла?
- Как закончить работу с файлом?
- Как обратиться к компоненте с заданным номером?
- Как подсчитать, сколько элементов в данном файле?
- Верно ли, что элементы файла должны быть одного типа и что файл отличается от массива только тем, что размер (количество элементов) файла произволен, а размер массива фиксирован?
- Можно ли, считав из файла пятый элемент, затем сразу же считать второй? Если нет, то какой можно?
- Верно ли, считав из файла пятый элемент, затем уже никогда нельзя считать его второй элемент?
- В какое место файла можно добавлять новые элементы: в начало, в середину, в конец, куда угодно, никуда?
- Если не переписывать файл заново, то значения каких его элементов можно менять: только первого, только последнего, каких угодно, никаких? А какие элементы можно удалять?
- Верно ли, что в одно и то же время нельзя считывать из файла и записывать в него? верно ли, что, начав считывать из файла, затем уже никогда нельзя записывать в него? А наоборот?
- Можно ли сравнивать файлы или присваивать один файл другому?
Примеры решения задач.
- Создать файл,содержащий информацию о работниках:табельный номер,фамилия,оклад. Создать другой файл,в котором содержится информация о работнике,имеющем максимальный оклад.
Program TipFile1;{Задача.Создать файл,содержащий информацию о работниках:табельный номер,фамилия,оклад. Создать другой файл,в котором содержится информация о работнике,имеющем максимальный оклад.Решение.Арсланов Ильдар, ЦНИТ "Северная Звезда" 03.04.2000.}Uses Crt;Type Dann=Record number:byte; Surname:string; oklad:integer;End;Var Zarpl,Tf:file of Dann; word:Dann; i,count:Integer; namef:string[12];Procedure VZapZarpl;Begin Writeln('Ввод записи ј ',FilePos(Zarpl)+1); With word do Begin Writeln('Работник ',i,'-ый'); Writeln('Табельный номер:'); Readln(number); Writeln('Фамилия:'); Readln(surname); Writeln('Оклад'); Readln(oklad); Write(Zarpl,word); End;End;Procedure File1Vvod;Begin Writeln('Введите имя файла:'); Readln(namef); Assign(Zarpl,namef); Rewrite(Zarpl); Writeln('Введите кол-во записей:'); Readln(count); For i:=1 to count do VZapZarpl; Writeln('Ввод информации о рабочих завершен'); Close(Zarpl); Readln;End;Procedure File2Make;Var namef1:string[12]; n,max:integer; surn1:string;Begin Max:=0; Writeln('Введите имя другого файла:'); Readln(namef1); Assign(Tf,namef1); Rewrite(Tf); Assign(Zarpl,namef); Reset(Zarpl); While not Eof(Zarpl) do begin Read(Zarpl,Word); For i:=1 to count do With Word do If oklad>max Then begin Max:=oklad; n:=number; surn1:=surname; end; end; Write(Tf,word); Close(Zarpl); Close(Tf); Reset(Tf); Seek(Tf,0); Writeln; Writeln('Вывод информации из нового файла,содержащего'); Writeln('информацию о работнике,имеющем наибольший оклад'); Writeln; While not Eof(tf) do begin Read(Tf,word); With Word do begin Writeln('Табельный номер ',n); Writeln('Фамилия ',surn1); Writeln('Оклад ',max); end; end; Close(Tf); Read;End;Begin ClrScr; File1Vvod; File2Make; ReadLn;End.
- Создать файл,содержащий информацию о работниках института.Найти средний стаж работы в институте.
Program TipFile2;{Задача.Создать файл,содержащий информацию о работниках института.Найти средний стаж работы в институте.Решение.Арсланов Ильдар, ЦНИТ "Северная Звезда" 03.04.2000.}Uses Crt;Type Dann=Record stag:byte; Surname,workname:string; oklad,year:integer;End;Var Zarpl:file of Dann; word:Dann; i,count,max:Integer; name:string[12];Procedure VVodZap;Begin With word do Begin Writeln('Работник ',i,'-ый'); Writeln('Фамилия:'); Readln(surname); Writeln('Год рождения:'); Readln(year); Writeln('Стаж работы:'); Readln(stag); Writeln('Должность:'); Readln(workname); Writeln('Оклад'); Readln(oklad); Write(Zarpl,word); End;End;Procedure FileVvod;Begin Writeln('Введите имя файла:'); Readln(name); Assign(Zarpl,name); Rewrite(Zarpl); Writeln('Введите кол-во работников:'); Readln(count); For i:=1 to count do VVodZap; Writeln('Ввод информации о работниках завершен'); Close(Zarpl); Readln;End;Procedure FileOpen;Var sr:real;Begin sr:=0; Assign(Zarpl,name); Reset(Zarpl); While not Eof(Zarpl) do begin Read(Zarpl,Word); With Word do sr:=max+stag; end; Sr:=(sr/count); Writeln('Средний стаж работы равен:',Sr:1:1,' лет'); Close(Zarpl); Read;End;Begin ClrScr; FileVvod; FileOpen; ReadLn;End.
- Создать файл телефонного справочника. По желанию пользователя можно создать,просмотреть, дополнить файл справочника,найти номер телефона по фамилии абонента,удалить компоненты файла-справочника.
Program TipFile3;{Задача.Создать файл телефонного справочника. По желанию пользователя можно создать,просмотреть, дополнить файл справочника,найти номер телефона по фамилии абонента,удалить компоненты файла-справочника.Решение.Арсланов Ильдар, ЦНИТ "Северная Звезда" 3.04.2000.}Uses Crt;Type sfio=string[20]; Sphone=string[10]; Rbook=record Fio:sfio; Phone:sphone; end; Var BFile:File of Rbook; Work:RBook; vid:byte; name:string[12];Procedure Name_File;Begin Write('Введите имя файла:'); Readln(name);End;Procedure VvodRec;Begin Writeln('Ввод записи ј ',FilePos(bFile)+1); With Work do Begin Write('Введите фамилию:'); Readln(Fio); Write('Введите номер телефона:'); Readln(phone); Write(BFile,Work); End;End;Procedure CrBPhone;Var i,count:integer;Begin Name_File; Assign(BFile,Name); Rewrite(BFile); Writeln('Введите число записей в справочнике '); Readln(count); For I:=1 to count do Vvodrec; Writeln('Создание справочника завершено'); Close(BFile);End;Procedure ProsRec;Begin Read(BFile,Work); With Work do begin Writeln('Запись ј ',FilePos(bFile)); Writeln('Фио: ',Fio,' телефон: ',Phone); end;End;Procedure ProsAllRec;Begin Name_File; Assign(BFile,name); Reset(BFile); Seek(BFile,0); Writeln('*******Вывод телефонного справочника**********'); While not Eof(BFile) do ProsRec; Writeln;End;Procedure IzmRec;Var NumRec:longint;Begin Name_File; Assign(BFile,name); Reset(BFile); Write('Укажите номер изменяемой записи:'); Readln(NumRec); Seek(BFile,NumRec-1); Writeln('Старое значение записи:'); ProsRec; Seek(BFile,NumRec-1); Writeln('Новое значение записи:'); VvodRec; Close(BFile);End;Procedure DopolRec;Var count,i:integer;Begin Name_File; Assign(BFile,name); Reset(BFile); Seek(BFile,FileSize(BFile)); Writeln('Введите число дополнительных записей '); Readln(count); For I:=1 to count do VvodRec; Writeln('Измененный файл содержит ',FileSize(BFile),' записи'); Close(BFile);End;Procedure FindFio;Var Maska:sfio; Flag:boolean;Begin Name_File; Assign(BFile,name); Reset(BFile); Writeln('Введите фамилию для поиска: '); Readln(Maska); Flag:=False; While not Eof(BFile) do begin Read(BFile,work); With work do If Pos(Maska,Fio)<>0 Then begin Flag:=True; Writeln('Фамилия: ',Fio,' телефон: ',phone); end; end; If not Flag Then Writeln('В справочнике нет абонентов с фамилией ',Maska); Close(BFile);End;Procedure DeleteFile;Begin Name_File; Assign(BFile,name); Reset(BFile); Truncate(BFile); Writeln('Компоненты файла были успешно удалены');End;Begin ClrScr; Repeat Writeln('ТЕЛЕФОННЫЙ СПРАВОЧНИК'); Writeln('Выберите вид работы:'); Writeln('1-Создание нового файла'); Writeln('2-Просмотр списка справочника'); Writeln('3-Изменение записи'); Writeln('4-Дополнение справочника'); Writeln('5-Поиск абонента'); Writeln('6-Удаление всех компонентов справочника'); Writeln('0-Выход'); Readln(vid); Case Vid of 1:CrBPhone; 2:ProsAllRec; 3:IzmRec; 4:DopolRec; 5:FindFio; 6:DeleteFile; 0:Exit; end; Writeln; Until Vid=0; Read;End.
Текстовые файлы
Особое место в языке Паскаль занимают текстовые файлы, компоненты которых имеют символьный тип. Для описания текстовых файлов в языке определен стандартный тип Тext:
var TF1, TF2: Text;
Текстовые файлы представляют собой последовательность строк, а строки – последовательность символов. Строки имеют переменную длину, каждая строка завершается признаком конца строки.
С признаком конца строки связана функция EOLn(var T:Text):Boolean, где Т – имя текстового файла. Эта функция принимает значение TRUE, если достигнут конец строки, и значение FALSE, если конец строки не достигнут.
Для операций над текстовыми файлами, кроме перечисленных, определены также операторы обращения к процедурам:
ReadLn (T) – пропускает строку до начала следующей;
WriteLn (T) – завершает строку файла, в которую производится запись, признаком конца строки и переходит к началу следующей.
Для работы с текстовыми файлами введена расширенная форма операторов ввода и вывода. Оператор
Read(T,X1,X2,...XK)
эквивалентен группе операторов
begin
Read(T,X1);
Read(T,X2);
Read(T,XK)
end;
Здесь Т – текстовый файл, а переменные Х1, Х2,...ХК могут быть либо переменными целого, действительного или символьного типа, либо строкой. При чтении значений переменных из файла они преобразуются из текстового представления в машинное.
Оператор
Write(T,X1,X2,...XK);
эквивалентен группе операторов
begin
Write(T,X1);
Write(T,X2);
Write(T,XK)
end;
Здесь Т – также текстовый файл, но переменные Х1, Х2,..., ХК могут быть целого, действительного, символьного, логического типа или строкой. При записи значений переменных в файл они преобразуются из внутреннего представления в текстовый.
К текстовым файлам относятся стандартные файлы INPUT, OUTPUT.
Рассмотренные ранее операторы ввода – вывода являются частным случаем операторов обмена с текстовыми файлами, когда используются стандартные файлы ввода-вывода INPUT, OUTPUT.
Работа с этими файлами имеет особенности:
– имена этих файлов в списках ввода-вывода не указываются;
– применение процедур Reset, Rewrite и Close к стандартным файлам ввода-вывода запрещено;
– для работы с файлами INPUT, OUTPUT введена разновидность функции EOLn без параметров.
– Турбо Паскаль вводит дополнительные процедуры и функции, применимые только к текстовым файлам, это SetTextBuf, Append, Flush, SeekEOLn, SeekEOF.
Процедура SetTextBuf (var f: Text; var Buf; BufSize: Word) служит для увеличения или уменьшения буфера ввода-вывода текстового файла f. Значение размера буфера для текстовых файлов по умолчанию равно 128 байтам. Увеличение размера буфера сокращает количество обращений к диску. Рекомендуется изменять размер буфера до открытия файла. Буфер файла начнется с первого байта переменной Buf. Размер буфера задается в необязательном параметре BufSize, а если этот параметр отсутствует, размер буфера определяется длиной переменной Buf.
Процедура Append (var f: Text) служит для специального открытия выходных файлов. Она применима к уже существующим физическим файлам и открывает их для дозаписи в конец файла.
Процедура Flush (var f: Text) применяется к открытым выходным файлам. Она принудительно записывает данные из буфера в файл независимо от степени его заполнения.
Функция SeekEOLn (var f: Text): Boolean возвращает значение True, если до конца строки остались только пробелы.
Компонентные файлы
Компонентный или типизированный файл – это файл с объявленным типом его компонент. Компонентные файлы состоят из машинных представлений значений переменных, они хранят данные в том же виде, что и память ЭВМ.
Описание величин файлового типа имеет вид:
type M= File Of T;
где М – имя файлового типа; Т – тип компоненты. Например:
type
FIO= String[20];
SPISOK=File of FIO;
var
STUD, PREP: SPISOK;
Здесь STUD, PREP – имена файлов, компонентами которых являются строки.
Описание файлов можно задавать в разделе описания переменных:
var
fsimv: File of Char;
fr: File of Real;
Компонентами файла могут быть все скалярные типы, а из структурированных – массивы, множества, записи. Практически во всех конкретных реализациях языка Паскаль конструкция "файл файлов" недопустима.
Все операции над компонентными файлами производятся с помощью стандартных процедур:
Reset, Rewrite, Read, Write, Close.
Для ввода-вывода используются процедуры:
Read(f,X);
Write(f,X);
где f – имя логического файла; Х – либо переменная, либо массив, либо строка, либо множество, либо запись с таким же описанием, какое имеет компонента файла.
Выполнение процедуры Read (f,X) состоит в чтении с внешнего устройства одной компоненты файла и запись ее в X. Повторное применение процедуры Read (f,X) обеспечит чтение следующей компоненты файла и запись ее в X.
Выполнение процедуры Write (f,X) состоит в записи X на внешнее устройство как одной компоненты. Повторное применение этой процедуры обеспечит запись X как следующей компоненты файла.
Для работы с компонентными файлами введена расширенная форма операторов ввода и вывода:
Read(f,X1,X2,...XK)
Write(f,X1,X2,...XK)
Здесь f – компонентный файл, а переменные Х1, Х2,..., ХК должны иметь тот же тип, что и объявленный тип компонент файла f.
Бестиповые файлы
Бестиповые файлы позволяют записывать на диск произвольные участки памяти ЭВМ и считывать их с диска в память. Операции обмена с бестиповыми файлами осуществляются с помощью процедур BlokRead и BlockWrite. Кроме того, вводится расширенная форма процедур Reset и Rewrite. В остальном принципы работы остаются такими же, как и с компонентными файлами.
Перед использованием логический файл
var f: File;
должен быть связан с физическим с помощью процедуры Assign. Далее файл должен быть открыт для чтения или для записи процедурой Reset или Rewrite, а после окончания работы закрыт процедурой Close.
При открытии файла длина буфера устанавливается по умолчанию в 128 байт. Турбо Паскаль позволяет изменить размер буфера ввода-вывода, для чего следует открывать файл расширенной записью процедур
Reset(var f: File; BufSize: Word);
или
Rewrite(var f: File; BufSize: Word);
Параметр BufSize задает число байтов, считываемых из файла или записываемых в него за одно обращение. Минимальное значение BufSize – 1 байт, максимальное – 64 Кбайта.
Чтение данных из бестипового файла осуществляется процедурой
BlockRead(var f: File; var X; Count: Word;
var QuantBlock: Word);
Эта процедура осуществляет за одно обращение чтение в переменную X количества блоков, заданное параметром Count, при этом длина блока равна длине буфера. Значение Count не может быть меньше 1. За одно обращение нельзя прочесть больше, чем 64 Кбайтов.
Необязательный параметр QuantBlock возвращает число блоков (буферов), прочитанных текущей операцией BlockRead. В случае успешного завершения операции чтения QuantBlock = Count, в случае аварийной ситуации параметр QuantBlock будет содержать число удачно прочитанных блоков. Отсюда следует, что с помощью параметра QuantBlock можно контролировать правильность выполнения операции чтения.
Запись данных в бестиповой файл выполняется процедурой
BlockWrite(var f: File; var X; Count: Word;
var QuantBlock: Word);
которая осуществляет за одно обращение запись из переменной X количества блоков, заданное параметром Count, при этом длина блока равна длине буфера.
Необязательный параметр QuantBlock возвращает число блоков (буферов), записанных успешно текущей операцией BlockWrite.
Воспользуйтесь поиском по сайту: