Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль - лекциии.doc
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
1 Мб
Скачать
☆

Текстові файли.

Текстові файли — це файли, в яких:

- Інформація представляється в текстовому вигляді (символи в коді ASCII);

- Порції інформації можуть поділятися на рядки. Признаком кінця

рядку є символ з кодом #13. Він може бути об'єднаний з символом переводу рядку #10;

- Кінець файлу позначається явно символом ^Z(#26);

- При записі чисел, рядків та логічних позначень вони перетворюються в символьний (текстовий) вигляд;

- При читанні чисел або рядків вони автоматично перетворюються з

текстового представлення в машинне.

Реально файл зберігається як суцільна послідовність символів і розбивається на рядки лише при його виведенні на екран або друк. Порожній текстовий файл містить лише один символ #26. Для роботи з текстовим файлом необхідно визначити файлову змінну Var f:text; , зв'язати її з фізичним файлом стандартною процедурою Assign, після чого файл можна відкривати.

В системній бібліотеці ТР визначені дві текстові змінні: Input та Output. Вони зв'язані з пристроєм 'CON' (клавіатура та екран : введення в 'CON'-це читання з клавіатури, а запис в 'CON' - це запис на екран) автоматично. Якщо в процедурі введення опущено ім'я файлу, то вважається, що введення йде із системного файлу Input (з клавіатури), а якщо ім'я файлу опущено в операторі виведення, то в файл Output (на екран).

Текст - орієнтовані процедури та функції.

Є ряд процедур та функцій, які крім стандартних, працюють тільки з

текстовими файлами:

1. SetTextBuf(Var f:text; VarBuf [;BufSize:word]) ;

Де f - файлова змінна типу text; Виf - люба змінна;

BufSize - необов'язкова змінна типу word. Процедура SetTextBuf служить для збільшення або зменшення буфера введення-виведення текстового файлу. Автоматично значення розміру буфера для текстового файлу рівне 128 байтів.

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

Збільшення буферу логічного файлу повинно відбуватися після зв'язування логічного файлу з фізичним, але до першої операції введення-виведення. Бажано змінювати буфер до відкриття файлу. Це дасть гарантію безпеки даних.

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

Буфер файлу починається з першого байту відведеного Buf і займає стільки байт скільки задано у необов'язковому параметрі BufSize.

Якщо при виклику процедури число BufSize не вказано, то вважається, що воно дорівнює розміру змінної Ви£

Задання BufSize більше ніж розмір самої Buf приведено до втрати даних суміжних по пам'яті з Buf.

Будучи встановленим одного разу для файлу, буфер не змінює свого місця і розміру до наступного виконання SetTextBuf або Assign з тією, ж файловою змінною.

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

Приклад: невірно заданий буфер.

Procedure TK(var f:text);

Var Buffer:array[1..16*1024] of Byte; (1)

FileName: Siring;

Begin

Readln(FileName);

Assign(var f; FileName);

SetTextBuf(var f, Buffer);

Rewrite(var f);

End;

Var ff:text;

Begin

TK(ff);

Write (ff,....);

.

.

.

{неважливо, що далі, тому що результат буде невірним)

end.

Невірно описаний рядок (1) : використовується локальна змінна, яка потім передається в процедуру. Справа в тому, що локальна змінна Buffer (зокрема в ній розміщується буфер файлу, який відкривається), існує лише під час виконання процедури. Після закінчення роботи процедури вона зникає. Область буферу стає недоступною і швидко заповнюється зовсім сторонніми значеннями, а переданий файл f, який викликається (ff) буде поводити себе непередбачувано. При всьому цьому не виникає ні помилки при компіляції, ні помилки під час підрахунку.

Якщо розмістити буфер в статичній змінній, то він з'їдає частину області даних або стеку, а він обмежений розміром 64 (Кбайта). Вигідно було б розмістити буфер в динамічній пам'яті (кучі), для цього потрібно оголосити вказівник на місце буфера в кучі.

Приклад:

Var ft: text;

Pbuf :pointer; {ссилка на буфер}

Const BufSize=1024; {розмір буферу}

Веgіп

Assign (ft, 'Text.doc');

GetMem(Pbuf,BufSize); {в пам 'яті відводиться блок, розмір

якого=буферу} {1}

SetTextBuf(ft,Pbuf ^,ВиfSize); {2}

{задається буфер в динамічній області}

Reset(ft);

.

.

.

Close(ft);

FreeMem(Pbuf,BufSize); {буфер видаляється з пам'яті} {3} End.

1. В пам'яті відводиться блок розміром з буфер.

2. Задається буфер в динамічній пам'яті.

3. Буфер видаляється із пам'яті, тобто звільняє місце. В цьому прикладі потрібно відводити і звільняти пам'ять під буфер, а в процедурі SetTextBuf обов'язково вказувати його розмір, так як блок пам'яті спочатку в Pbuf не знає свого розміру. (Рекомендується обирати розмір буферу кратним 512 байтам)

2. Append (Var f: text);

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

Якщо Append застосовується до неіснуючого файлу, то виникає помилка лічби часу. Новий файл може бути створений тільки процедурою Rewrite. Після відкриття файлу процедурою Append запис в нього буде здійснюватися з того місця, де знаходився признак кінця файлу (#26). При необхідності змінити текстовий буфер потрібно зробити це до відкриття файлу процедурою Append. Взагалі ця процедура нічим не відрізняється від Rewrite, крім способу відкриття файлу з кінця.

3. Flush (Var f: text);

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

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

Дана процедура не закриває файл і не впливає на послідовність виведення. Flush може знайти застосування при роботі зі стандартними файлами MS-DOS, зокрема з пристроями друку або паралельними і послідовними портами. При роботі з ними даним не має потреби залишатися в буфері, а процедура Flush, поставлена після write, знімає ефект затримки буферу файлу.

4. EOLN(Var f: text): Boolean;

Ця функція аналізує поточне положення в текстовому файлі, відкритому для читання. EOLN повертає значення True, якщо наступною операцією буде прочитаний признак кінця рядка #13, або кінець файлу #26. False дана функція видає в усіх інших випадках. Функція ніби відчуває результат наступного читання та аналізує його. Необхідність в EOLN виникає всякий раз, коли зарані невідомо, де зустрінеться кінець рядка.

Приклад: Хай є файл DT.DAT з стовпчиками цифр:

12.3 15.6 7.5 6.1 15.0 #13 #10

17.6 16.9 5.8 100 98.19 #13 #10

53.4 0.0

#26

Як автоматично визначити число стовпчиків в ньому і налагодити читання за допомогою EOLN.

Program рr;

Var f: text; {логічний текстовий файл}

Kol: integer; {лічильник кількості стовпчиків}

A: real;

Begin

Assign(Var f; 'DT.DAT');

Reset(f);

Kol:=0;

While not EOLN (f) do begin

Read(f,a); {читання вправо по рядку} Inc(kol); {збільшити на 1 кіл-ть стовпчиків} End;

Reset(f); {повернення на одну позицію у файлі}

.

.

.

Close(f);

End.

Є різновид EOLN без параметрів, В цьому випадку вважається, що дія її відноситься до стандартного файлу INPUT, тобто введення з клавіатури. Тут функція EOLN повертає True не перед, а після проходження признаку кінця рядка: зразу після натиснення клавіші Enter. Більш того від EOLN без параметрів важко дочекатися значення False. Вона підвішує програму і повертає управління наступному оператору тільки після того, як натиснена клавіша введення (Enter). В мові Pascal є спосіб організувати паузу до натискання введення, а саме Write (EOLN).

5. SeekEOLN (Var f:text): boolean;

Ця функція є найближчою родичкою EOLN. Файл f повинен бути текстовим і відкритим для читання. Функція повертає значення True, якщо до кінця рядку (#13) або кінця файлу (#26) можуть бути зчитані тільки проміжки (#32) або символи табуляції (#9). Значення True повернеться також в тому випадку, коли поточне значення в файлі безпосередньо передує символам #13#26. На відміну від EOLN дана функція ніби бачить кінець рядка, або файла через проміжки або знаки табуляції. SeekEOLN орієнтована головним чином на роботу з текстовими файлами чисел.

6. SeekEOF(Var f:text): boolean;

Для даної функції символи кодів #9 #13 #32 є прозорими, і якщо крізь них видно кінець файлу #26, то функція повертає значення True, у всіх інших випадках повернеться значення False. Функція дозволяє знайти змістовий кінець файлу, а не фізичний. Це корисно при роботі з числами (рідше з символами):

While Not ЕОF(f) do

Read(f,a);

Цей цикл зупиниться тільки після повного виснаження файлу, навіть коли останні 1024 рядки були пусті. Якщо ж цей цикл переписати так,

While Not SeekEof(f) do

Read(f,a);

то він буде працювати більш ефективно.

Функція SeekEOF може бути застосована тільки для відкритих текстових файлів.