Read(f, а); read(f, b, c); read(f, d);

AssignFile(f,fname);

 

6.3. Вивід даних у файл

Безпосередньо вивід в текстовий файл здійснюється за допомогою інструкції write або writeln. У загальному вигляді ці інструкції записуються таким чином:

write (Файлова змінна, Список виводу) ;

writeln (Файлова змінна, Список виводу);

де:

· Файлова змінна — це змінна, що ідентифікує файл, в який виконується вивід;

· Список виводу – це розділені комами імена змінних, значення яких треба вивести у файл. Окрім імен змінних в список виводу можна включати стрічкові константи.

Наприклад, якщо змінна f є змінною типу TextFiie, то інструкція виводу значень змінних x1 і х2 у файл може бути такій:

write(f, 'Корені рівняння', x1, х2);

Відмінність між інструкціями write і writeln полягає в тому, що інструкція writeln після виведення всіх значень, вказаних в списку виводу, записує у файл символ "новий рядок".

 

6.4. Відкриття файлу для виводу

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

Можливі наступні режими відкриття файлу для запису в нього даних:

· перезапис (запис нового файлу поверх того, що існує або створення нового файлу);

· додавання в існуючий файл.

Для того, щоб відкрити файл в режимі створення нового файлу або заміни що існує, необхідно викликати процедуру Rewrite(f), де f — файлова змінна типу TextFile.

Для того, щоб відкрити файл в режимі додавання до вже існуючих даних, що знаходяться в цьому файлі, потрібно викликати процедуру Append(f), деf — файлова змінна типу TextFile.

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

 

Рис. 6.1.Діалогове вікно програми запису-додавання у файл

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

Ім'я файлу потрібно ввести під час роботи в полі Edit1. Можна задати зумовлене ім'я файлу під час розробки форми додатку. Для цього треба привласнити значення, наприклад data.txt, властивості Edit1.Text.

 

Лістинг 6.1. Створення нового або заміщення існуючого файлу

procedure TForm1.Button1Click(Sender: TObject);

Var

f: TextFile; // файл

fName: String[80]; // ім'я файлу

i: integer;

Begin

fName := Edit1.Text;

AssignFile(f, fName);

Rewrite(f); // відкрити для перезапису

// запис у файл

for i := 0 to Memo1.Lines.Count do // рядки нумеруються з нуля

writeln(f, Memo1.Lines[i]);

CloseFile(f); // закрити файл

MessageDlg('Дані ЗАПИСАНІ у файл ',mtInformation,[mbOk],0);

End;

У лістингу 6.2приведена процедура, яка запускається натисненням командної кнопки Додати.Вона відкриває файл, ім'я якого вказане в полі Edit1, і додає в нього вміст поля Memo1.

Лістинг 6.2. Додавання в існуючий файл

procedure TForm1.Button2Click(Sender: TObject);

Var

f: TextFile; // файл

fName: String[80];// ім'я файлу

i: integer;

Begin

fName := Edit1.Text;

AssignFile(f, fName);

Append(f); // відкрити для додавання

// запис у файл

for i:=0 to Memo1.Lines.Count do // рядки нумеруються з нуля

writeln(f, Memo1.Lines[i]);

CloseFile(f); // закрити файл

MessageDlg('Дані ДОДАНІ у файл ', mtInformation, [mbOk], 0);

End;

 

6.5. Помилки відкриття файлу

Спроба відкрити файл може завершитися невдачею і викликати помилку часу виконання програми. Причин невдачі при відкритті файлів може бути декілька. Наприклад, програма спробує відкрити файл на гнучкому диску, який не готовий до роботи (не закрита шторка накопичувача, або диск не вставлений в накопичувач). Інша причина — відсутність файлу, що відкривається в режимі додавання (файлу немає — додавати нeма куди).

При запуску програми з Delphi у разі помилки під час відкриття файлу виникає виключення, і на екрані з'являється діалогове вікно з повідомленням (мал. 6.2).

Рис. 6.2.Приклад повідомлення про помилку відкриття файлу (програма запущена з Delphi)

Якщо програма запускається з Windows, то вікно з повідомленням про помилку виглядає інакше (мал. 6.3).

Рис. 6.3.Приклад повідомлення про помилку відкриття файлу . (програма запущена з Windows)

Програма може узяти на себе завдання контролю за результатом виконання інструкції відкриття файлу. Зробити це можна, перевіривши значення функції IOResult (input-Output Result — результат введення/виводу). Функція IOResuit повертає 0, якщо операція введення/виводу завершилася успішно; інакше — код помилки (не нуль).

Для того, щоб програма змогла перевірити результат виконання операції введення/виводу, потрібно дозволити їй це робити. Для цього треба перед інструкцією виклику процедури відкриття файлу помістити директиву компілятору — рядок {$I-}, який забороняє автоматичну обробку помилок введення/виводу. Ця директива повідомляє компілятор, що програма бере на себе контроль помилок. Після інструкції відкриття файлу слід помістити директиву {$I+}, поновлюючу режим автоматичної обробки помилок введення/виводу.

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

Рис. 6.4.Алгоритм відкриття файлу з обробкою можливої помилки

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

AssignFile(f,filename);

{$I-}

Append(f) // відкрити для додавання

{$I+}

if IOResult<> 0 // помилка відкриття

then Rewrite(f); // відкрити для запису

// відкрити існуючий або новий файл

Закриття файлу

Перед завершенням роботи програма повинна закрити всі відкриті файли. Це робиться викликом процедури close. Процедура close має один параметр — ім'я файлової змінної. Приклад використання процедури:

Close(f);

Приклад програми

Наступна програма веде просту базу даних. При кожному її запуску на екрані з'являється діалогове вікно (мал. 7.5), в поля якого користувач може ввести дату і температуру повітря.

Рис. 6.5.Діалогове вікно програми База даних "Студенти-викладачі"

Дата вводиться в поле Edit1, температура — в полі Edit2. Текст програми приведений в лістингу 7.3.

Лістинг 6.3, Проста база даних (запис у файл)

unit pogoda_;

Interface

Uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

Type

TForm1 = class(TForm)

Edit1: TEdit; // дата

Edit2: TEdit; // температура

Button1: TButton; // кнопка Додати

Label1: TLabe1;

Label2: TLabe1;

procedure FormActivate(Sender: TObject);

procedure ButtonlClick(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction); private

{Private declarations }

public

{Public declarations }

end;

Var

Form1: TForm1;

Implementation

{$R *.dfm}

Const

DBNAME = 'c:\Test\ListofPeople.db';

var

db: TextFile; // файл — база даних

procedure TForm1.FormActivate(Sender: TObject);

Begin

AssignFile(db, DBNAME);.

{$I-}

Append(db);

if IOResult = 0 then

Begin

Edit1.Text := DateToStr(Date); // отримати поточну дату

Edit2.SetFocus; // курсор в полі Edit2

End

Else begin

Rewrite(db);

if IOResult <>0 then begin

// зробити недоступними поля введення // і командну кнопку

Edit1.Enabled := False;

Edit2.Enabled := False;

Button1.Enabled := False;

ShowMessage('Помилка створення '+DBNAME);

End;

End;

End;

// клацання на кнопці Додати

procedure Tform1.Button1Click(Sender: TObject);

Begin

if (Length(Edit1.text)=0) or (Length(Edit2.text)=0)

Then

ShowMessage('Помилка введення даних.' +#13+'Bce поля

повинні бути заповнені.')

else writeln(db, Edit1.text, ’ , ' ,Edit2.text);

End;

// Подія OnClose виникає при закритті форми

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

Begin

CloseFile(db); // закрити файл БД

End;

End.

Для програми поліморфізм

procedure TForm1.Button2Click(Sender: TObject); var i:integer; // индекс st:string; // список begin for i:=1 to SZL do if list[i] <> NIL then st:=st + list[i].info + #13; // ShowMessage('Список'+#13+st); writeln(db, 'Список' + st); end;

 

Файл бази даних відкриває процедура FormActivate, яка обробляє подію onActivate. Подія OnActivate виникає у момент активізації форми, тому процедура запускається автоматично, при активізації форми додатку. Якщо операція відкриття файлу завершується успішно, то в полі Edit1 записується поточна дата. Інформація про поточну дату повертає функція Date. Для перетворення повертаного функцією Date значення (числа типу Double) в зручну для сприйняття форму використовується функція Dateiostr. Після запису дати в полі Editi процедура обробки події onActivate із застосуванням методу setFocus встановлює курсор в полі введення температури. Якщо в процесі відкриття або створення нового файлу виникає помилка, то процедура робить недоступною кнопку Додатиі виводить інформаційне повідомлення.

Процедура TForm1.Button1Click (процедура обробки події onclick) запускається натисненням кнопки Додати(Button1). В результаті введена інформація записується в базу даних — файл pogoda.db. Перед виконанням запису програма перевіряє, чи всі поля форми заповнені, і, якщо не все, то виводить інформаційне повідомлення.

В результаті роботи процедури в кінець файлу pogoda.db буде доданий рядок, що містить дату (число, місяць, рік) і температуру.

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

Звернете увагу, що список виведення інструкції writein складається з трьох елементів. Після виводу у файл дати (Edit1.text) у файл записується пропуск, а затем— температура (Еdit2.txt). Якщо температуру записати у файл відразу після дати, то числа, відповідні року і температурі, зіллються в одну послідовність цифр.

Закриває базу даних процедура TFormi.Formciose, яка обробляє подію enclose, що виникає при закритті форми додатку.

Після декількох запусків програми файл pogoda.db можливо, наприклад, таким:

9.05.2001 10 10.05.2001 12 11.05.2001 10 12.05.2001 7

 

Зчитування з файлу

Програма може вводити початкові дані не тільки з клавіатури, але і з текстового файлу. Для того, щоб скористатися цією можливістю, потрібно оголосити файлову змінну типу TextFile, призначити їй за допомогою інструкції AssignFile ім'я файлу, з якого прочитуватимуться дані, відкрити файл для читання (введення) і прочитати (ввести) дані, використовуючи інструкцію read або readln.

 

 

Відкриття файлу

Відкриття файлу для введення (читання) виконується викликом процедури Reset, що має один параметр — файлову змінну. Перед викликом процедури Reset за допомогою функції AssignFile файлова змінна повинна бути пов'язана з конкретним файлом.

Наприклад, наступні інструкції відкривають файл для введення:

AssignFile(f, 'c:\data.txt');

Reset(f);

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

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

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

Фрагмент програми, текст якого приведений в лістингу 6.4, використовує значення функції lOResult для перевірки результату відкриття файлу. Якщо спроба відкрити файл викликає помилку, то програма виводить діалогове вікно з повідомленням про помилку і запитом на підтвердження повторного відкриття файлу.

 

Лістинг 6.4. Обробка помилки відкриття файлу (фрагмент програми)

Var

fname : string[80]; // ім'я файлу

f : TextFile; // файл

res : integer; // код помилки відкриття файлу (значення lOResult)

answ : word; // відповідь користувача

Begin

fname := 'a:\test.txt';

AssignFile (f, fname);

Repeat

{$I-}

Reset(f); // відкрити файл для читання

{$I+}

res:=IOResult;

if res <> 0 then

answ:= MessageDlg('Помилка відкриття '+ fname+#13 +'Повторити

спробу?',mtWarning, [mbYes, mbNo],0); until (res= 0) OR

(answ = mrNo);

if res <> 0

then exit; // завершення процедури

// тут інструкції, які виконуються

// у разі успішного відкриття файлу

End;

 

 

Зчитання даних з файлу

Читання з файлу виконується за допомогою інструкцій read і readln, які в загальному вигляді записуються таким чином:

read( Файлова змінна, Список змінних);

readln( Файлова змінна, Список змінних);

де:

· Файлова змінна — змінна типуTextFile;

· Список змінних — імена змінних, розділені комами.

 

Зчитування чисел

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

Наприклад, якщо текстовий файл а:\data. txt містить наступні рядки:

23 15 45 28 56 71

то в результаті виконання інструкцій:

AssignFile(f, 'a:\data.txt');

Reset(f); // відкрити для читання

read(f, а); read(f, b, c); read(f, d);

значення змінних будуть наступними: а = 23, b = 15, з = 45, d = 28.

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

Тому в результаті виконання інструкцій

AssignFile(f,'a:\data.txt');

Reset(f);

Readln(f, а);

Readln(f, b, c);

Readln(f, d);

значення змінних будуть наступними: а = 23, b = 45, з = 28, d = 56.

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

 

Зчитування стрічок

У програмі стрічкова змінна може бути оголошена з вказівкою довжини або без неї.

Наприклад:

strichka1:string[10];

strichka2:string;

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

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

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

Наприклад, текстовий файл f- reads.txt містить рядки:

Петрова Маша Васильев Антон Цой Лариса

У табл. 6.1 приведено декілька варіантів оголошення змінних, інструкції читання з файлу freinds.txt і значення змінних після виконання інструкцій читання.

Таблиця 6.1.Приклади читання рядків з файлу

           
  Оголошення Інструкція зчитування змінних з файлу Значення змінних після зчитування з файлу  
  fnam: string[15] Readln (f, fnam, name) fnam= ' Петрова’  
  name: string[10]   name= ' Маша  
  fnam, name: string; Readln (f, fnam, name) fam= ' Петрова Маша '  
      name= ' '  
  drug: string[80] Readln (f, drug) drug =' Петрова Маша'  
             

6.9. Мітка кінця файлу

Хай на диску є деякий текстовий файл. Потрібно в діалогове вікно вивести вміст цього файлу. Рішення задачі задоволене очевидно: треба відкрити файл, прочитати перший рядок, потім другий, третій і так далі до тих пір, поки не буде досягнутий кінець файлу. Але як визначити, що прочитаний останній рядок, досягнутий кінець файлу?

Для визначення кінця файлу можна скористатися функцією EOF (End of File — кінець файлу). У функції EOF один параметр — файлова змінна. Значення функції EOF рівне False, якщо прочитаний елемент даних не є останнім у файлі, тобто можливе подальше читання. Якщо прочитаний елемент даних є останнім, то значення EOF рівне True.

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

У лістингу 6.5 приведена процедура, яка виконує поставлене завдання. Вона читає рядки з файлу, ім'я якого ввів користувач під час роботи програми, і виводить ці рядки в полі Memo. Вікно програми приведене на мал. 6.6.

Рис. 6.6.Вікно програми Зчитування з файлу

Лістинг 6.5. Читання з файлу

unit rd_;

Interface

Uses

Windows, Messages, SysUtils, Variants, Classes

Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;

Type

TForm1 = class(TForm)

Button2: TButton;

Edit1: TEdit;

Memo1: TMemo;

Button1: TButton;

procedure Button2Click(Sender: TObject);

procedure ButtonlClick(Sender: TObject); private

{ Private declarations ) public

{ Public declarations } end;

Var

Form1: Tform1;

Implementation

{$R *.dfm}

// клацання на кнопці Відкрити

procedure TForm1.Button1Click(Sender: TObject);

var

f: TextFile; // файл

fName: String[80]; // ім'я файлу

buf: String[80]; // буфер для читання з файлу

Begin

fName := Edit1.Text;

AssignFile(f, fName);

{$I-}

Reset(f); // відкрити для читання

{$I+}

if IOResult<> 0 then

Begin

MessageDlg('Помилка доступу до файлу ' + fName mtError,[mbOk],0);

exit;

end;

// читання з файлу

while not EOF(f) do begin

readln(f, buf); // прочитати рядок з файлу

Memo1.Lines.Add(buf); // додати рядок в полі Memo1

End;

CloseFile(f); // закрити файл

End;

// клацання на кнопці Зберегти — запис у файл

procedure Tform1.Button2Click(Sender: TObject);

Var

f: TextFile; // файл

fName: String[80]; // ім'я файлу

i: integer;

Begin

fName := Edit1.Text; AssignFile(f, fName);

Rewrite(f); // відкрити для перезапису

// запис у файл

for i:=0 to Memo1.Lines.Count do // рядки нумеруються з нуля

writeln(f, Memo1.Lines[i]);

CloseFile(f); // закрити файл

MessageDlg('Дані записані у файл ', mtlnformation,[mbOk],0);

End;

End.

Для організації обробки файлу використана інструкція циклу while, яка забезпечує перевірку значення функції EOF перед кожним читанням, у тому числі і перед першим.

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

Додавання чергового прочитаного з файлу рядка в полі Memo виконується застосуванням методу Add до властивості Lines.


Питання:

1. Що таке файли?

2. Для чого призначена файлова змінна

3. Запис даних у файл

4. Зчитування даних з файлу

5. Для чого призначена функція lOResult

6. Мітка кінця файлу

 

Література: