2. Опрацювання типізованих файлів.

Типізований файл являє собою файл з компонент певного типу, які називаються записами.

Запис - це структура даних, що складається з фіксованого числа компонентів, названих полями. Поля можуть бути різних типів. Кожному полю задається ім’я, так званий ідентифікатор поля. Ідентифікатор поля використовується при організації доступу до компонентів запису.

Визначення типу запису починається зарезервованим словом record (запис), за ним іде список полів запису. Наприкінці списку полів запису ставиться зарезервоване слово end (кінець).

Список полів являє собою послідовність розділів запису, відділених друг від друга крапкою з комою. Кожний розділ складається з одного або декількох ідентифікаторів, що відокремлюються один від одного комами, слідом за якими іде або двокрапка, або ідентифікатор типу, або опис типу (дескриптор). Таким чином, кожний розділ запису визначає тип одного або декількох полів.

ПРИКЛАД

Type

 Student = record

 Name:string[30];

 Course:1..4;

 Group:string[7];

 End;

 Month = (jan,feb,mar,apr,may,jun,july,aug,sep,oct,nov,dec);

 Data = record

 Day, Year:integer;

 Mon:month;

 End;

 Album=record

 Name:string[15];

 Year:integer;

 end;

Перший тип запису – Student – містить три поля. Всі поля різнотипові. Два з них являють рядкову величину, одне – цілочисельний діапазон. Другий тип ( Data) має два однотипових поля, які описані через кому. Третє поле має тип, визначений користувачем . Помітимо, що порядок опису полів ніякої ролі не відіграє, він визначається користувачем. Третій тип (Album) має поля, які використовуються у двох попередніх типах. Це дозволяється синтаксисом, оскільки повні імена об’єктів будуть різними. При цьому типи полів можуть бути як однаковими (поле Year), так і різними (поле Name).

Змінні типу запис вводяться аналогічно стандартним типам:

Var

 stud1, stud2 : student;

 new_date : data;

 comp_disk : album;

 

Відзначимо, що так само, як і для даних типу масив, дозволяється виконувати операції присвоювання між цілими записами однакових типів. У всіх інших випадках опрацювання записів можна здійснювати покомпонентно, причому в межах тих операцій, які дозволяються типом відповідних полів. Виключення складають лише операції вводу-виводу для файлів. Для опрацювання компонента запису (тобто конкретного поля) ім’я поля вказується через крапку після імені запису: stud1.name –поле name запису stud1 .

ПРИКЛАДИ:

stud1:=stud2; {допустима операція}

stud1:=new_date; {недопустима операція різні типи}

read(stud1); {недопустима операція}

readln(stud1.name, stud1.course, stud1.year);

{допустима операція для вказаних типів полів}

comp_disk.year:=new_date;

{допустима операція – однакові типи полів}

readln(new_date.mon);

{недопустима операція – для типу даних

користувача не визначена така операція}

При використанні типів записів так, як це показано вище, одержується досить довгі оператори. Було б зручніше, якби ми могли звернутися до певних полів запису так, якби вони були простими змінними. Цю функцію виконує оператор приєднання with. Він “відкриває” запис таким чином, що ідентифікатори полів можуть використовуватися як ідентифікатори змінних. Оператор має такий формат:

with імена записів do

оператори;

end;

Слідом за зарезервованим словом with в операторі іде список змінних величин запису, відділених один від одного комами. За списком змінних іде зарезервоване слово do. Завершує оператор with зарезервоване слово end. В тілі оператора приєднання тепер можна вказувати неповні імена компонентів записів, а лише імена полів. Оператор автоматично визначить, до якого саме запису виконати вказані оператори. У заголовкові оператора приєднання можна вказувати декілька імен змінних типу запис. При цьому пріоритет при наявності однакових полів буде мати той запис, ім’я якого записане раніше.

ПРИКЛАД:

with stud1 do

 readln(name);

 read(course);

 group:=’gr-00-1’;

end;

Визначення типізованого файлу починається зарезервованими словами file of, після яких задається тип компонентів файла, описаний як звичайно, а за ним іде ідентифікатор попередньо визначеного типу файлів.

ПРИКЛАД:

type

 Student = record

 Name:string[30];

 Course:1..4;

 Group:string[7];

 End;

data = file of student;

var

 p: data; {типізований файл}

 s: student;

Типом компонентів файла може бути будь-який тип, крім типу файл (тобто не існує файлу файлів). Змінні типу файл не можна використовувати ні в операторах присвоювання, ні у виразах. Типізований файл є файлом прямого доступу, тобто, він дозволяє одночасно і читання і запис даних.

Далі використовується опис даних, наведений в останньому прикладі. Розглянемо основні процедури, які використовуються для всіх типів файлів.

Опрацювання будь-якого файлу складається з трьох етапів:

зв’язування файлової змінної з дисковим файлом та відкриття файлу:

власне обробка файлу( тобто, обробка його компонент);

закриття файлу.

Як вже зазначалось раніше, всі дані зберігаються на зовнішніх носіях у вигляді дискових файлів. Тому при опрацюванні файлових структур даних потрібно спочатку зв’язати файлову змінну з конкретним дисковим файлом. Власне, для цього і використовується файлова структура – щоб одержати доступ до фізичних даних на дискові. Для цього призначена стандартна процедура assign. Вонавстановлює відповідність між файловою змінною та дисковим файлом. Синтаксис процедури:

assign(f, st);

де f – ім’я файлової змінної;

st – рядкова величина, яка задає повне ім’я дискового файлу.

Ця процедура повинна передувати всім іншим процедурам роботи з файлами. Крім того, не допускається використовувати процедуру для вже відкритого файлу (тобто, який в даний момент опрацьовується).

Процедура rewrite призначена для відкриття та створення файлу (тобто, підготовки його до опрацювання). Якщо файл (дисковий) вже існує, то він руйнується, і його створення починається з першої компоненти. . Синтаксис процедури:

rewrite(f),

де f – ім’я файлової змінної.

Процедура reset призначена для відкриття файлу. В цьому режимі з типізованого файлу можна читати дані, і записувати дані до файлу. Синтаксис процедури:

reset(f),

де f – ім’я файлової змінної.

Якщо відповідного дискового файлу не існує, виникає помилка.

ПРИКЛАД:

assign(p,’c:\users\mydata.dat’);

assign(t,’c:\list.txt’);

assign(g,’document.doc’);

reset(p);

rewrite(t);

reset(g,16000);

Обробка компонент файлу залежить від завдання, що розв’язується. Основними при цьому є операції читання даних з файлу та запису даних у файл.

Процедура read призначена читання даних з файла. Синтаксис:

read(f, n),

де f – ім’я файлової змінної,

n – ім’я змінної, в яку зчитуються дані з файла.

Тип змінної повинен відповідати типові файла. Після виконання операції покажчик файла переміщується до наступного компонента.

Процедура write призначена для запису даних до файлу. Синтаксис процедури:

write(f, n),

де f – ім’я файлової змінної,

n – ім’я змінної, в яку зчитуються дані з файлу.

Тип змінної також повинен відповідати типові файла. Після виконання операції покажчик файла також переміщується до наступного компонента.

Зауважимо, на відміну від вводу даних з клавіатури та виводу даних на екран процедури readln та writeln для файлових структур не використовуються. Крім того, список параметрів відповідних процедур може містити лише одну змінну.

ПРИКЛАД:

read(p,s);

write(p,s);

При відкритті файла покажчик завжди встановлюється на перший запис, який має номер 0. Для встановлення покажчика файла на потрібну позицію (для доступу до потрібного запису) призначена стандартна процедура seek. Синтаксис процедури:

seek(f,m),

де f – файлова змінна; .

m– змінна типу longint, яка задає номер запису.

Для визначення поточної файлової позиції використовується функція filepos типу longint, яка має такий синтаксис:

filepos(f),

де f – змінна файлового типу.

Для того, щоб визначити довжину файла в записах, використовується функція filesize типу longint, яка має такий синтаксис:

filesize(f),

де f – змінна файлового типу.

ПРИКЛАД:

begin

 reset(p); {відкриваємо файл}

 read(p,s); {читаємо перший запис}

 n:=filesize(p);{взнаємо кількість записів файла}

 seek(p,n); {встановлюємо покажчик на кінець файла}

 write(p,s); {дописуємо в файл новий запис}

end.

У мові реалізовані такі стандартні функції, призначені для опрацювання файлів. Функція eof - логічна, результат якої дорівнює true, якщо покажчик файла знаходиться наприкінці дискового файла, тобто за останнім компонентом файла. Якщо покажчик файла знаходиться в іншому місці, то результат функції буде дорівнює false .

ПРИКЛАД:

type

 Student = record

 Name:string[30];

 Course:1..4;

 Group:string[7];

 End;

data = file of student;

var

 p: data; {типізований файл}

 s: student;

begin

 reset(p); {відкриваємо файл}

 while not eof(p) do {поки є записи у файлі}

 begin

 read(p,x);{читаємо черговий запис }

 writeln(x.name);{друкуємо прізвище студента}

 end;

Процедура close призначена для закриття файлу. При цьому файл стає недоступний для обробки, але його можна відкрити ще раз за допомогою розглянутих вище процедур.

Формат процедури

close(f)

де f – ім’я файлової змінної.

Якщо дана процедура відсутня в програмі, то після її завершення ПАСКАЛЬ автоматично закриє всі відкриті файли.

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 
75 76 77 78 79  Наверх ↑