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

pascal_lections

.pdf
Скачиваний:
14
Добавлен:
02.04.2015
Размер:
1.43 Mб
Скачать

S:=’Супер строка’;

insert(‘длинная ’,S,7); {‘Супер длинная строка’}

End.

Function length (S: string) :integer;

Функция возвращает текущую длину строки S.

Function pos (subst: string; S: string): byte;

Функция отыскивает место первого вхождение подстроки subst в строку S. Возвращает номер позиции, где начинается найденная подстрока. Если подстрока не найдена, возвращает 0.

Procedure str (X [:Width [:Decimals]]; var S:string);

Процедура преобразования числа Х любого целого или вещественного типа в строку символов.

Procedure val (S; var X; var code:integer);

Процедура преобразования строки S во внутреннее представление числа X (целое или вещественное). Code – код ошибки. Code=0, если преобразование успешно завершилось; иначе Code= номер символа, на котором произошла ошибка преобразования.

Var I, Code :integer; S :string;

Begin S:=’что-то-там__как-то-там’;

Val(S,I,Code); If Code<>0 then

writeln('Error at position ', Code) else

writeln(‘Value = ’, I);

End.

Function UpCase (ch: char) :char;

Функция преобразовывает символ ch в соответствующую заглавную букву, если ch является строчной буквой латинского алфавита. Для остальных символов значение не меняется.

Function chr (X: byte) :char;

Функция возвращает символ из таблицы символов, в соответствии с заданным номером X.

Function ord (ch :char) :longint;

Функция возвращает порядковый номер символа ch в таблице символов.

var

 

 

x:real;

 

 

y:integer;

 

 

s, s1:string;

 

 

begin

 

 

s:=concat('12','345');

s=’12345’

s1:=copy(s,3,length(s)-2);

s1=’345’

 

insert('+',s1,2);

s1=’3+45’

delete(s,pos('2',s),3);

s=’15’

 

str(789,s);

s=’789’

 

val('3.14',x,y);

x=3.14

y=0

val('3,14',x,y);

x=0

y=2

end.

 

 

41

Файлы и файловые переменные.

Опр.: Файл – линейная последовательность элементов, каждый из которых имеет тип элемента (или тип записи) файла. Каждый элемент файла имеет номер. Первый элемент файла имеет нулевой индекс.

ВПаскале имеются три класса файлов:

-типизованный файл

-текстовый файл,

-нетипизованный файл.

Описание файловой переменной:

Var F: file of тип_файла;

F1: file of integer;

- типизированный файл

F2: file;

- нетипизированный файл

F3: text;

- текстовый файл

Перед использованием: файловая переменная должна быть связана с внешним файлом с помощью вызова процедуры Аssign.

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

Когда связь с внешним файлом установлена, файловая переменная должна быть «открыта». Существующий файл можно открыть с помощью процедуры Reset, а новый файл можно создать и открыть с помощью процедуры Rewrite.

Текстовые файлы, открытые с помощью процедуры Reset доступны только для чтения, а открытые с помощью процедуры Rewrite – только для записи.

Типизованные и нетипизованные файлы всегда допускают как чтение, так и запись, независимо от того были они открыты с помощью процедуры Reset или Rewrite.

Когда начинается выполнение программы, всегда автоматически открываются стандартные текстовые файловые переменные Input и Оutput (ввод и вывод). Input – это доступный только для чтения файл, связанный с клавиатурой. Оutput – это доступный только для записи файл, связанный с дисплеем.

Обычно доступ к файлам организуется последовательно, то есть, когда элемент считывается с помощью стандартной процедуры Read или записывается с помощью стандартной процедуры Write, текущая позиция файла перемещается к следующему по порядку элементу файла.

К типизованным и нетипизованным файлам можно организовать прямой доступ с помощью процедуры Sееk, которая перемещает текущую позицию файла к заданному элементу. Для определения текущей позиции в файле и текущего размера файла можно использовать функции

FilePos и FileSize.

Когда программа завершает обработку файла, он должен закрываться с помощью процедуры Close. После полного закрытия файла, связанный с ним внешний файл обновляется. Затем файловая переменная может быть связана с другим внешним файлом.

42

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

Procedure

Assign

присваивает имя внешнего файла файловой переменной

Procedure

ChDir

выполянет смену текущего каталога

Procedure

Close

закрывает открытый файл

Function

EOF

возвращает для файла состояние end-of-file (конец файла)

Procedure

Erase

стирает внешний файл

Procedure

GetDir

возвращает текущий каталог на заданном диске

Function

IOResult

возвращает целое значение, являющееся состоянием последней

 

 

выполненной операции ввода-вывода

Procedure

MkDir

создает подкаталог

Procedure

Rename

переименовывает внешний файл

Procedure

Reset

открывает существующий файл

Procedure

Rewrite

создает и открывает новый файл

Procedure

RmDir

удаляет пустой подкаталог

Типизированные файлы. Процедура Seek.

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

Пример 1. Создает файл, содержащий квадраты 10 чисел типа real.

Program FileEx3;

Var file1: file of real; R: real;

N: integer; Begin

Assign(file1,’data.dat’);

Rewrite(file1); For N:=1 to 10 do Begin

R:=sqr(N);

Write(file1,R); {запись числа в файл в двоичном внутреннем формате}

End;

Close(file1);

End.

Пример 2. Считывает с экрана числа в диапазоне от 1 до 10 и выдает их квадраты, записанные в файле

Program FileEx4; Var

File1 :file of real; R: real;

N: integer; Begin

Assign(file1,’data.dat’);

Reset(file1);

Write(‘введите число (1-10) : ’);

Readln(N); //While N>0 do //Begin

Seek(file1,N-1); {передвигаем указатель текущей позиции файла в заданное место}

Read(file1,R);

Writeln(‘квадрат ’,N,’ равен ’,R);

//End;

End.

43

Seek(var имя_файла; номер_компоненты :longint)

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

Процедуры BlockRead и BlockWrite.

Процедуры BlockRead и BlockWrite аналогичны по смыслу процедурам Read и Write, однако они работают на с отдельными записями, а с наборами записей.

BlockRead(var имя_файла :file; var буфер; размер: word [; var результат :word]) – считывает одну или более записей из файла в буфер.

BlockWrite(var имя_файла :file; var буфер; размер: word [; var результат :word]) – записывает одну или более записей из буфера в файл.

Имя_файла – нетипизированная файловая переменная.

Буфер – любая переменная, в которую происходит считывание или из которой происходит запись. Размер – выражение типа word, определяющее число записей для считывания или записи. Результат – переменная типа word, определяющая результат операции.

Пример копирования файлов из одного в другой, блоками 2 Кб.

var

FromF, ToF: file;

NumRead, NumWritten: Word; Buf: array[1..2048] of Char;

begin

Assign(FromF, ParamStr(1)); { Open input file } Reset(FromF, 1); { Record size = 1 } Assign(ToF, ParamStr(2)); { Open output file } Rewrite(ToF, 1); { Record size = 1 }

Writeln('Copying ', FileSize(FromF), ' bytes...'); repeat

BlockRead(FromF, Buf, SizeOf(Buf), NumRead); BlockWrite(ToF, Buf, NumRead, NumWritten);

until (NumRead = 0) or (NumWritten <> NumRead); Close(FromF);

Close(ToF);

end.

Процедуры Erase и Rename.

Процедуры Erase и Rename работают с внешними файлами.

Erase(var file_name :file) – удаляет файл.

Rename(var file_name :file; new_file_name :string) – переименовывает файл.

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

Program FileEx7; var

F1: file; BEGIN

if ParamCount<>2 then writeln('wrong parameters') else

begin assign(F1,ParamStr(1));

writeln('rename: ',ParamStr(1),' into ',ParamStr(2));

44

rename(F1,ParamStr(2));

erase(F1);

end;

END.

Текстовые фалы

Текстовые фалы являются разновидностью типизированных файлов типа file of char. Для описания текстовых файлов используется предопределенный тип text.

Var TextFile : text;

В текстовых фалах помимо признака конца файла EOF (код символа = 26, Ctrl-Z), присутствует еще признак конца строки EOLN, состоящий на самом деле из последовательности двух символов: «возврат каретки» (код символа = 13) и «перевод строки» (код символа = 10).

Отличия файла text от file of char:

1.автоматическое преобразование числовых данных в цепочку символов при записи значений в файл, и обратное преобразование символов, являющихся числами, в числовое значение при выполнении операции чтения в переменные соответствующих числовых типов.

2.текстовые файлы не имеют прямого доступа, то есть к ним не применимы процедуры seek, blockread и blockwrite.

3.присутствует признак конца строки.

4.для чтения/записи текстовых файлов разрешается использовать процедуры readln и writeln, которые недопустимы для остальных типов файлов.

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

Program SymbolsCount; Var ch:char;

LineCount,CharCount:longint;

F:text; BEGIN

LineCount:=0;

CharCount:=0;

Assign(F,ParamStr(1));

Reset(F);

While not EOF(F) do Begin

While not EOLN(F) do Begin

Read(F,ch);

inc(CharCount);

end;

ReadLn(F); {переход на следующую строку} inc(LineCount);

end;

Close(F);

if LineCount=0 then writeln(‘пустой файл’) else

begin

writeln(‘число строк = ’, LineCount:6); writeln(‘число символов = ’, CharCount:6); writeln(‘среднее число символов в строке = ’,

CharCount/LineCount:1:4);

end;

END.

45

Один и тот же физический файл можно писать/читать как типизированный файл различных

типов.

Пример. Сначала в файл типа CHAR записывается ряд символов, а затем этот же физический файл открывается как файл типа BYTE, и на печать выводятся коды ASCII, записанных в него символов.

Program CharToByte. Uses crt;

Var

F1 : file of char;

F2 : file of byte; C : char;

B : byte; BEGIN

Clrscr;

Assign(F1,’test.dat’);

Rewrite(F1);

For C:=’0’ to ‘9’ do write(F1,C); For C:=’A’ to ‘J’ do write(F1,C);

Close(F); {-----------}

Assign(F2,’test.dat’);

Reset(F2);

While not EOF(F2) do Begin

Read(F2,B);

Write(B:4);

End;

Close(F2);

END.

Пример. Программа сортировки файла с прямым доступом методом простого обмена (метод «пузырька»)

Program FileSort; Uses crt;

Var

F : file of integer; X, Y : integer;

I, J : longint; BEGIN

clrscr; {$I-}

Assign(F, ‘sort.dat’);

Reset(F); {$I+}

if IOResult<>0 then begin

writeln(‘ошибка открытия файла’); halt(1);

end;

clrscr;

writeln(‘исходный файл:’); for I:=1 to FileSize(F) do begin

Read(F,X);

46

Write(X:8);

End;

WriteLn;

Close(F); {-----------} Reset(F);

For I:=FileSize(F)-1 downto 1 do

{«всплывание» очередного макс. элемента на i–ю позицию} for J:=0 to I-1 do

begin seek(F,J); read(F,X,Y); if X>Y then begin

seek(F,J);

write(F,Y,X);

end;

end;

Close(F); {-----------} Reset(F);

WriteLn(‘отсортированный файл:’);

For I:=1 to FileSize(F) do Begin

Read(F,X);

Write(X:8);

End;

Close(F);

END.

Имея открытую файловую переменную можно получить имя файла

uses strings, dos;

var f:text; FileName: string; begin

assign(f,'text.txt');

rewrite(f); writeln(f,'Hello, world!'); close(f);

FileName:=StrPas(PChar(@TextRec(f).Name)); writeln(FileName);

end.

GetFAttr(var имя_файла; var атрибут: word) – возвращает атрибуты файла SetFAttr(var имя_файла; var атрибут: word) – устанавливает атрибуты файла

Постоянная

Значение

ReadOnly

$01

Hidden

$02

SysFile

$04

VolumeID

$08

Directory

$10

Archive

$20

AnyFile

$3F

FSplit(путь:PathStr; var каталог:DirStr; var имя:NameSrt; var расширение:ExtStr); - разбиение полного имени файла на составляющие (путь, имя, расширение)

FExpand(путь :PathStr) :PathStr; - расширяет имя файла до полного имени.

FSearch(путь:PathStr; список_каталогов:String) :PathStr; - ищет файл в списке каталогов. Каталоги в списке должны быть отделены двоеточием

Тип строки

Определение

ComStr

String[127]

PathStr

String[79]

DirStr

String[67]

47

NameStr

String[8]

ExtStr

String[4]

FilePos(var имя_файла) :longint; – возвращает текущую позицию для заданного файла FileSize(var имя_файла) :longint; – возвращает текущий размер файла

Truncate(var file_name) – обрезает файл от текущей позиции до конца

EOF(var file_name) :Boolean – =true, если указатель стоит на символе конца файла EOLN(var file_name) :Boolean – =true, если указатель стоит на символе конца строки

Записи.

Запись, в отличие от массивов, множеств и файлов, является составной структурой данных. Если отдельно взятый массив, множество или файл всегда включает в себя элементы одного типа, то записи могут объединять в единое целое любое число структур данных других типов: простых переменных, массивов, множеств и записей. Но не допускается использование полей записи файлового типа. В вариантных записях допускается использование только того варианта полей, который соответствует установленной константе поля-признака.

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

Type

String10 = string[10];

String20 = String[20];

TStudentCard = record

SurName :string20; {фамилия}

Name :string20; {имя}

FatherName :string20; {отчество}

Year :integer; {год.рожд.}

HomeAddress :string; {адрес}

GroupCode : string10; {группа}

Predmet = record {оценки за последний семестр}

MatAn,

Programming,

Phylos :byte;

End;

End;

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

type

TGroup = array [1..25] of TStudentCard; Var

Group3056, Group3051 :TGroup;

В этом случае будут корректны следующие обращения к полям:

Group3056[1].Name := ’Sergey’;

Group3056[1].Year := 1980; Group3056[1].Predmets.MatAn := 5; Group3051[6] := Group3051[5];

48

Для упрощения работы с записями в Pascal имеется специальный оператор присоединения

with.

С использованием этого оператора вышеприведенные операторы будут записаны в таком

виде:

With Group3056[1] do

Begin

Name := ‘Sergey’;

Year := 1980;

Predmet.MatAn := 5;

End;

Group3051[6] := Group3051[5];

При заполнении информацией структур типа «запись» с помощью процедур Read и Raedln, необходимо помнить, что допускается ввод только некоторых стандартных типов данных. Поэтому, в процедурах Read и readln могут располагаться идентификаторы только самых внутренних полей записи.

Вариантные записи.

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

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

type

TPredmetSemestr1 = record

MatAn1, {математический анализ} Programming1, {программирование} Phylos :byte; {философия}

End;

TPredmetSemestr2 = record

MatAn2,

Electronica,

Programming2,

Geometry :byte;

End;

TStudentCard = record

{фиксированная часть записи}

SurName :string20; {фамилия} Name :string20; {имя}

FatherName :string20; {отчество} Year :integer; {год.рожд.} HomeAddress :string; {адрес} GroupCode : string7; {группа}

{вариантная часть записи} case Semestr :byte of

49

1: (

Sem1 :TPredmetSemestr1;

);

2: (

Sem2 :TpredmetSemestr2;

);

End;

Var

Group3056, Group3051 :TGroup;

...

with Group3056[3] do begin

{заполнение фиксированной части записи} SurName := ‘Иванов’;

Name := ‘Иван’; FatherName := ‘Иванович’;

Year := 1980;

HomeAddress := ‘г.Вырица, ул.Ленина, д.2, кв.3’;

GroupCode := ‘3056’;

{заполнение вариантной части записи} Semestr:=1; {установка признака семестра}

With Sem1 do Begin

MatAn1 := 3; Programming1 := 4; Phylos := 5;

End;{with sem1} End;{with group3056}

НО В вариантных записях НЕ ДОПУСКАЕТСЯ ИСПОЛЬЗОВАТЬ одинаковые имена идентификаторов для вариантных компонент записи.

пример не корректен:

TStudentCard = record

...

{вариантная часть записи} case Semestr :byte of

1:( MatAn, LineAlgebra, Programming, Phylos :byte; );

2:( MatAn, Electronic, Programming, Geometry :byte; );

End;

Будет выдана ошибка ‘Duplicate identifier (MatAn)’

50

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