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

Алгоритмические языки высокого уровня. Курс лекций

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
940 Кб
Скачать

завершается с сообщением об ошибке, если указанный файл не най- ден (если f типизированный файл, то процедурой Reset он от- крывается для чтения и записи одновременно).

Rewrite(f) открывает для записи файл, с которым связана файловая переменная f. После успешного выполнения этой про- цедуры файл готов к записи в него первого элемента. Если указан- ный файл уже существовал, то все данные из него уничтожаются.

Close(f) закрывает открытый до этого файл с файловой пе- ременной f. Вызов процедуры Close необходим при завершении работы с файлом. Если по какой-то причине процедура Close не будет выполнена, файл все же будет создан на внешнем устройстве, но содержимое последнего буфера в него не будет перенесено.

EOF(f): boolean возвращает значение TRUE, когда при чтении достигнут конец файла. Это означает, что уже прочитан по- следний элемент в файле или файл после открытия оказался пуст.

Rename(f, NewName) позволяет переименовать физический файл на диске, связанный с файловой переменной f. Переимено- вание возможно после закрытия файла.

Erase(f) уничтожает физический файл на диске, который был связан с файловой переменной f. Файл к моменту вызова про- цедуры Erase должен быть закрыт.

IOResult возвращает целое число, соответствующее коду последней ошибки ввода-вывода. При нормальном завершении опе- рации функция вернет значение 0. Значение функции IOResult необходимо присваивать какой-либо переменной, так как при каж- дом вызове функция обнуляет свое значение (функция IOResult работает только при выключенном режиме проверок ошибок ввода- вывода или с ключом компиляции {$I-}).

Пример процедуры определения наличия типизированного файла записей на диске

Описание. Если файла нет, то создается пустой файл, указатель устанавливается в его начало, если файл существует, то указатель просто устанавливается в его начало.

Program Test; Type

t_r=record fio:string[20]; {ФИО}

yb :integer; {Год рождения} p :real; {Зарплата}

81

end;

f_t= file of r_t; Procedure NoFile(var f:f_t);

{В процедурах файловые переменные указываются как выход-

ные - var} begin

Assign(f,'c:\mydir\my.dat'); {связывание файловой пере-

менной f с физическим файлом}

{$I-} {директива компилятора отключающая контроль ошибок ввода-вывода}

Reset(f); {попытка открыть файл}

{$I+} {директива компилятора включающая контроль ошибок ввода-вывода}

If IOResult<>0 then Rewrite(f); {если ошибка, то создать новый файл}

end;

Работа с типизированными файлами. Типизированный файл это последовательность компонент любого заданного типа (кроме типа «файл»). Доступ к компонентам файла осуществляется по их порядковым номерам. Компоненты нумеруются, начиная с 0. После открытия файла указатель (номер текущей компоненты) стоит в его начале на нулевом компоненте. После каждого чтения или записи указатель сдвигается к следующему компоненту.

Write(f, список переменных) записывает в файл f

всю информацию из списка переменных.

Read(f, список переменных) процедура читает из фай- ла f компоненты в указанные переменные. Тип файловых компо- нент и переменных должны совпадать. Если будет сделана попытка чтения несуществующих компонент, то произойдет ошибочное за- вершение программы. Необходимо либо точно рассчитывать количе- ство компонент, либо перед каждым чтением данных делать провер- ку их существования (функция eof).

Seek(f, n) процедура смещает указатель файла f на n-ю позицию. Нумерация в файле начинается с 0.

FileSize(f):longint функция возвращает количество компонент в файле f.

FilePos(f):longint функция возвращает порядковый номер текущего компонента файла f.

Truncate(f) процедура отсекает конец файла, начиная с те- кущей позиции включительно.

82

Работа с текстовыми файлами. Текстовый файл это совокуп-

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

Чтение из текстового файла:

Read(f, список переменных); ReadLn(f, список переменных);

Процедуры читают информацию из файла f в переменные. Спо- соб чтения зависит от типа переменных, стоящих в списке. В пере- менную char помещаются символы из файла. В числовую перемен- ную пропускаются символы-разделители, начальные пробелы и счи- тывается значение числа до появления следующего разделителя. В переменную типа string помещается количество символов, равное длине строки, но только в том случае, если раньше не встретились символы конца строки или конца файла. Отличие ReadLn от Read в том, что в нем после прочтения данных пропускаются все оставшие- ся символы в данной строке, включая метку конца строки. Если спи- сок переменных отсутствует, то процедура ReadLn(f) пропускает строку при чтении текстового файла.

Запись в текстовый файл:

Write(f, список переменных); WriteLn(f, список переменных);

Процедуры записывают информацию в текстовый файл. Способ записи зависит от типа переменных в списке (как и при выводе на экран). Учитывается формат вывода. WriteLn от Write отлича- ется тем, что после записи всех значений из переменных записывает еще и метку конца строки (формируется законченная строка файла).

Append(f) процедура открывает текстовый файл для добав- ления информации к его концу.

Работа с нетипизированными файлами. Нетипизированные файлы это последовательность компонент произвольного типа.

Открытие нетипизированного файла:

Reset(f, BufSize) ; Rewrite(f, BufSize);

Параметр BufSize задает число байт, считываемых из файла или записываемых в него за одно обращение. Минимальное значение BufSize – 1 байт, максимальное – 64 К байт (если BufSize не указан, то по умолчанию он принимается равным 128).

Чтение данных из нетипизированного файла:

83

BlockRead(f, X, Count, QuantBlock);

Эта процедура осуществляет за одно обращение чтение в пере- менную X количество блоков, заданное параметром Count, при этом длина блока равна длине буфера. Значение Count не может быть меньше 1. За одно обращение нельзя прочитать больше чем 64 К байт. Необязательный параметр QuantBlock возвращает число блоков, прочитанных текущей операцией BlockRead. В случае успешного завершения операции чтения QuantBlock = Count, в случае аварийной ситуации параметр QuantBlock бу- дет содержать число удачно прочитанных блоков. Отсюда следует, что с помощью параметра QuantBlock можно контролировать правильность выполнения операции чтения.

Запись данных в нетипизированный файл:

BlockWrite(f, X, Count, QuantBlock);

Эта процедура осуществляет за одно обращение запись из пере- менной X количество блоков, заданное параметром Count, при этом длина блока равна длине буфера. Необязательный параметр QuantBlock возвращает число блоков, записанных успешно теку- щей операцией BlockWrite. Для нетипизированных файлов можно использовать процедуры Seek, FIlePos и FileSize, аналогично соответствующим процедурам типизированных файлов.

Пример программы

Описание: в программе создается файл прямого доступа, в файл вводятся данные, и осуществляется его вывод на экран.

Program Test; uses crt; type

student=record n: integer; name=string[10]; end;

var i:integer; s:student;

f:file of student; procedure create_file begin

assign(f, ‘c:\11.dat’); rewrite(f);

for i:=1 to 4 do begin

84

seek(f,i);

readln(S,n,s.name);

write(f,s);

end;

close(f);

end;

procedure write_file(i:integer); begin

assign(f,’c:\11.dat’);

reset(f);

seek(f,1);

readln(S,n,S,name);

write(f,s);

close(f);

end; begin

readln(i); case I of

1: create_file; 2:write_file; end;

assign(f,’c:\11.dat’); for i:=1 fo 4 do

begin seek(f,i); gotoxy(13,i);

write(S.name,S.name);

end;

close(f);

end.

4.2.5. Строки

Для обработки строковой информации в Turbo Pascal введен стро- ковый тип данных. Строкой в Pascal называется последовательность из определенного количества символов. Количество символов после- довательности называется длиной строки.

Синтаксис

var s: string[n]; var s: string;

где n – максимально возможная длина строки целое число в диапа- зоне 1…255 (если этот параметр опущен, то по умолчанию он при- нимается равным 255).

Строковые константы записываются как последовательности сим- волов, ограниченные апострофами. Допускается формирование строк с использованием записи символов по десятичному коду (в виде

85

комбинации # и кода символа) и управляющих символов (комбина- ции ^ и некоторых заглавных латинских букв).

Пример: 'Текстовая строка' #54#32#61 'abcde'^A^M;

Пустой символ обозначается двумя подряд стоящими апострофа- ми (если апостроф входит в строку, то при записи он удваивается).

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

Имеется простой доступ к отдельным символам строковой пере- менной: i-й символ переменной st записывается как st[i].

Если st – это 'Строка', то st[1] – это 'С', st[2] – это 'т', st[3] – 'р' и т.д.

Над строками определены операции:

слияния (конкатенации), обозначается знаком +

a := 'Turbo'; b := 'Pascal'; c := a + b; пере-

менная c приобретет значение 'TurboPascal'.

сравнения <, >, =, <>, <=, >=. Две строки сравниваются посим- вольно, слева направо, по кодам символов. Если одна строка короче другой, то недостающие символы короткой строки заменяются сим- волом с кодом 0.

Процедуры и функции для работы со строками

Delete(Var S:String; N,M:Integer) удаляет M

символов из строки S, начиная с позиции N.

s := 'Система Turbo Pascal'; delete(s,8,6); {s будет равно 'Система Pascal'}

Insert(SubS:String; Var S :String; N:Integer)

вставляет

подстроку SubS в строку

S, начиная с позиции N.

s :=

'Система Pascal';

insert('Turbo ',s,9);

{s будет равно 'Система Turbo Pascal'}

Str(X:Integer; Var S:String) возвращает представ-

ление числа X в его символьной форме S.

Val(S:String; Var X, Code:Integer) возвращает представление символов строки S в ее числовой форме X. Пара- метр Code содержит признак ошибки преобразования (если Code = 0, то это свидетельствует об успешно произошедшем пре-

86

образовании ошибки нет). Процедура преобразует строковую за- пись числа, содержащуюся в S, в числовое представление, поме- щая результат в Х (Х может быть как целой, так и действительной переменной). Если в S встречается недопустимый (с точки зрения правил записи чисел) символ, то преобразование не происходит, а в Code записывается позиция первого недопустимого символа. Вы- полнение программы при этом не прерывается, диагностика не выда- ется.

Chr(X:Byte): Char возвращает символ с заданным поряд- ковым номером X.

Сoncat(S1[,S2 ,...,SN]):String выполняет сцепку

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

Copy(S:String; N, M:Integer):String возвращает подстроку из строки S, начиная с позиции N и длиной M симво- лов.

s := 'Система

Turbo Pascal';

s2

:= copy(s,

1, 7); {s2 будет равно 'Система'}

s3

:= copy(s,

9, 5); {s3 будет равно 'Turbo'}

s4

:= copy(s,

15, 6); {s4 будет равно 'Pascal'}

Length(S:String):Byte возвращает количество симво- лов в строке S.

n := length('Pascal'); {n будет равно 6}

Ord(X:Char):LongInt возвращает порядковый номер сим- вола X в таблице кодов символов.

Pos(SubS,S:String):Byte возвращает номер позиции,

начиная с которой в строке S

располагается подстрока SubS (если

значение равно 0, то

S

не содержит SubS).

s := 'Система Turbo Pascal';

x1 := pos('Pascal', s); {x1 будет равно 15}

x2 := pos('Basic', s); {x2 будет равно 0}

UpCase(c:char):char; Если c строчная латинская буква, то функция возвращает соответствующую прописную латинскую букву, в противном случае строчной символ.

87

Пример программы

Описание: в программе в строке заменяются все вхождения под- строки child на подстроку children (метод решения перебор всех символов строки аналогично удалению и вставке элементов в одномерном массиве).

program zamena; var

s1,k,s,st:string; i,d: byte;

begin

writeln('введите строку'); readln(st);

s:='child';

d:=length(s);

s1:='children';

for i:=length(st)-d+1 downto 1 do begin

k:=copy(st,i,d); if k=s then

begin delete(st,i,d); insert(s1,st,i);

end;

end;

writeln('измененная строка: ',st); end.

4.3. Процедурные типы

Основное назначение этих типов дать гибкие средства передачи функций и процедур в качестве фактических параметров обращения к другим процедурам и функциям.

Для объявления процедурного типа используется заголовок про- цедуры (функции), в котором опускается ее имя, например:

type

Prod = Procedure (a, b, c: Real; var d: Real); Proc2 = Procedure (var a, b) ;

Рrос3 = Procedure;

Func1 = Function: String;

Func2 = Function (var s: String): Real;

Существует два процедурных типа: тип-процедура и тип- функция.

88

Пример программы

Описание: иллюстрация механизма передачи процедур в качестве фактических параметров вызова при выводе на экран таблицы двух функций:

sin1(х) = (sin(x) + 1) * ехр(-х) cos1(x) = (cos(x) + 1) * exp(-x)

{Вычисление и печать значений этих функций реализуются в процедуре PRINTFUNC, которой в качестве параметров передают- ся номер позиции N на экране, куда будет выводиться очеред- ной результат (с помощью этого параметра реализуется вывод в две колонки), и имя нужной функции}

Uses CRT; type

Func = Function (x: Real) : Real; Procedure PrintFunc (XPos: Byte; F:Func) ;

{Осуществляет печать функции F . XPos - горизонтальная по- зиция начала вывода }

const

np = 20; {Количество вычислений функций} var

х : Real; i : Integer; begin {PrintFunc}

for i := 1 to np do begin

x := i * (2 * pi / np) ; GotoXY (XPos, WhereY) ; WriteLn (x:5:3, F(x):18:5) end

end; {PrintFunc}

Function Sin1fx: Real): Real; far; begin

sinl := (sin(x) + 1) * exp(-x) end;

Function Cos1(x: Real): Real; far; begin

cosl := (cos(x) + 1) * exp(-x) end;

begin {основная программа} ClrScr; {Очищаем экран}

PrintFunc (1, sin1); GotoXY (1,1); {Переводим курсор в ле-

вый верхний угол} PrintFunc (40, cos1) end.

Для установления правильных связей функций SIN1 и COS1 с процедурой PRINTFUNC они должны компилироваться с расчетом на дальнюю модель памяти. Вот почему в программу вставлены стан-

89

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

Стандартные процедуры (функции) Pascal не могут передаваться рассмотренным способом.

В программе могут быть объявлены переменные процедурных ти- пов:

var

p1 : Proc1; f1, f2 : Func2;

р : array [1..N] of Proc1;

Переменным процедурных типов допускается присваивать в ка-

честве значений имена соответствующих подпрограмм. После такого присваивания имя переменной становится синонимом имени подпро- граммы:

type

Proc = Procedure (n: word; var a: Byte); var

ProcVar: Proc; x, у : Byte;

Procedure Procl(x: word; var y: Byte); far; begin

if x > 255 then

у:= x mod 255 else

у:= Byte(x) end;

begin {Главная программа} ProcVar := Proc1;

for x := 150 to' 180 do begin

ProcVar (x + 100, y); Write (y:8)

end end.

Такие присваивания допустимы и для параметров-функций:

type

FuncType = Function (i : Integer) : Integer; var

VarFunc : FuncType; i : Integer;

Function MyFunc (count : Integer) : Integer; far; begin

.......

end; {MyFunc}

90

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]