Смекни!
smekni.com

Паскаль робота з файлами (стр. 3 из 4)

end;

end;

end;

procedure OutPutFile;

var St : Student; Ch : char;

begin

writeLn('Чи бажаєте дивитися дані про студентів ? "Y"/"N" ');

readln(Ch);

if (Ch = 'Y') or (Ch = 'y') then

begin

while not eof(Fi) do

begin

read(Fi, St); clrscr;

writeln('Прізвище : ', St.SName);

writeln('Ім''я: ', St.Name);

writeln('Середній бал: ', St.Ball);

readln;

end;

end;

close(Fi);

end;

begin

clrscr; writeln('Програма друкування даних про студентів');

openfile; outPutfile;

end.

Задачі

1.* Пояснити, що задає та як використовується пpогpама

program filcrout;

type Tel = record nam : string; num : integer end;

var f : fileof Tel; x : Tel; s : string; eel : boolean;

procedure readel ( var x : Tel );

begin

x.num:=0; readln ( x.nam);

if x.nam <> '' then readln ( x.num )

end;

begin

writeln ( 'Введіть ім''я файла:' ); readln ( s );

assign ( f, s ); rewrite ( f );

repeat

readel ( x ); eel := (x.nam = '');

ifnot eel then write ( f, x );

until eel;

reset(f);

whilenot eof ( f ) do

begin

read ( f, x ); writeln ( x.num, ': ', x.nam )

end

end.

2.* Переписати програму з прикладу 13.2, щоб у разі порожнього файла її виконання не завершувалося аварійно.

3. Переписати програму з прикладу 13.2, щоб числа не копіювалися в інший файл, а друкувалися на екрані.

4.* Написати пpоцедуpу пpисвоювання файлів шляхом копіювання.

5.* Написати функцію пеpевіpки побайтової pівності двох файлів.

6.* Написати пpоцедуpу дописування до елементів пеpшого файла елементів другого, із зберіганням pезультату

а) в новому файлі; б) в першому файлі.

7.* Написати пpоцедуpу виведення змісту файла з даними про студентів на екpан "стоpінками": після друкування на екрані даних про чергових 5 студентів виводиться запит щодо продовження, і виконання програми призупиняється до того, як користувач підтвеpдить або не підтвердить пpодовження.

4. Прямий доступ у системі Турбо Паскаль

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

Але послідовний доступ елементів не завжди зручний. Чи не замислювався читач над тим, як запрограмувати читання з типізованого файла елемента за його номером або його заміну, додавання чи вилучення ?

Зрозуміло, що задати читання елемента за номером k можна так:

reset(f);

for i:=1 to k-1 do read(f, x); {пропущено k-1 елемент – доступний k-й}

read(f, x).

Для заміни елемента файла за його номером k можна "вийти на нього" шляхом читання попередніх. Далі можна скористатися одним недоліком системи Турбо Паскаль. Справа в тім, що система дозволяє в стані читання записувати в файл значення змінних (і лише змінних!). Отже, заміну елемента можна описати так:

reset(f);

for i:=1 to k-1 do read(f, x);

{пропущено k-1 елемент - доступний якраз k-й}

x:=...; write(f, x).

Описати в такому ж дусі вилучення й додавання елемента до файла ми залишаємо вправою для наддопитливих читачів. Але все це "штучки", якими користуватися не варто.

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

Основною є процедура SEEK. У її виклику задається ім’ я файлової змінної та номер того елемента файла, який стає доступним після виконання виклику. Номер задається виразом типу LongInt. Наприклад, після виклику

Seek ( f, 2)

доступним стає третій елемент, оскільки нумерація починається з 0:

f0 f1 f2 f3 ... fN

­

Значення саме цього елемента буде читатися за виконання виклику процедури введення read чи цьому елементу буде щось присвоюватися за виконання write. В обох випадках доступним стане наступний елемент:

f0 f1 f2 f3 ... fN

­

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

У системі Турбо Паскаль є також кілька допоміжних процедур, що застосовуються разом із процедурою Seek.

Функція FILEPOS задає повернення номера доступного елемента. Єдиним аргументом у її виклику є ідентифікатор файлової змінної, а повертається значення типу LongInt. Наприклад, за останнього зображеного значення файлової змінної f присвоювання

A := FilePos ( f );

надає змінній А типу LongInt значення 3.

Для визначення загальної кількості елементів у файлі використовують функцію FILESIZE. Її единим параметром є ідентифікатор файлової змінної, і з її виклику повертається значення типу LongInt. Наприклад, значенням змінної N типу LongInt після присвоювання

N := FileSize ( f )

стає кількість елементів у файлі.

Зрозуміло, що використовуючи у програмі виклик процедури seekв парі з викликами read або write, ми зможемо прочитати будь-який елемент файла чи зробити заміну його значення.

Зокрема, за допомогою процедур seek, filesizeі write можна розширити файл, дописуючи значення нового елемента в кінець:

seek ( f, filesize ( f ));

write ( f, v ).

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

f0 f1 f2 ... fN

­

а після виклику write значення v записується в новий елемент, після чого файловий вказівник переміщається вправо:

f0 f1 f2 ... fN fN+1

­

Процедура TRUNCATE задає знищення решти файла, починаючи від доступного елемента. Наприклад, після виконання викликів

seek(f, 3); truncate(f)

елементи з 3-го по останній знищуються, а залишаються з номерами 0, 1 і 2.

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

Приклад 4. Наведемо програму, яка задає вилучення непотрібних елементів файла, тобто його стискання.

Нехай у файлі Group.dat зберігається інформація про студентів групи: прізвище, ім’я та середній бал. З клавіатури задається прізвище студента, який вибув – запис про нього треба вилучити з файла.

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

program OutFromGroup;

type Student = record

Sname, Name : string[20];

Ball : real;

end;

var Fi, Fo : fileof Student; { інформаційний та допоміжний файл }

FileName: string; { ім’ я файла }

procedure OpenFile;

begin

writeln('Задайте ім''я файла'); readln(FileName);

assign(Fi, FileName); reset(Fi);

assign(Fo, 'NewFile.dat'); rewrite(Fo);

end;

procedure ClearFile; { Процедура стискання файла }

var St : Student; { Змінна для обміну }

StudtoOut : string[20];

begin

writeln('Задайте прізвище студента, що вилучається:');

readln(StudtoOut);

while not eof(Fi) do

begin

read(Fi, St);

if St.SName <> StudtoOut then

write(Fo, St)

end;

close(Fi);

close(Fo);

{Виклики процедур модуля System }

Erase(Fi); {для знищення}

ReName(Fo, FileName); {та переіменування файла }

end;

begin

OpenFile;

ClearFile;

end.

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

У першому алгоритмі використовується допоміжний файл, в який переписуються всі елементи, що передують заданому.

Відкрити основний та допоміжний файли.

У циклі переписати з основного файла в допоміжний всі елементи, номери яких менші заданого. Для цього можна використати допоміжну змінну того ж типу, що і в елементів файла.

У допоміжний файл записати значення, яке треба вставити.

У циклі переписати з основного файла в допоміжний усі елементи, що залишились.

Закрити основний та допоміжний файли.

Знищити основний файл.

Переіменувати допоміжний файл в основний.

У другому алгоритмі замість допоміжного файла використовуються дві допоміжні змінні того ж типу, що і в елементів файла, та допоміжна змінна-лічильник типу LongInt для запам’ятовування поточного місця вставки.

Першій допоміжній змінній присвоїти значення, яке треба вставити в файл.

Встановити файловий вказівник на місце вставки за допомогою процедури Seek.

Запам’ятати місце вставки в змінній-лічильнику за допомогою функції FilePos.

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

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

В циклі, поки файл не прочитано:

записати в доступний елемент файла значення з першої змінної;

запам’ятати нове місце вставки, збільшивши лічильник;

першій допоміжній змінній присвоїти значення другої;

прочитати значення того елемента, на який вказує файловий вказівник, і присвоїти другій допоміжній змінній;