пʼятниця, 4 листопада 2011 р.

ОРГАНІЗАЦІЯ ВВЕДЕННЯ-ВИВЕДЕННЯ ДАНИХ У ФАЙЛ


Познайомимося з організацією введення-виведення даних у файл (з файлу). Для введення-виведення інформації в файли використовують процедури READ (READLN) і WRITE (WRITELN).

Введення даних з файлу процедура Read(<Файлова змінна>, <Об’єкт  (Об'єкти) введення>); або зчитування даних процедура Readln(<Файлова змінна>, <Об’єкт (Об'єкти) введення>);


Приклади:

Assign(F,‘TextFill.TXT’); {встановлення зв’язку між файловою змінною та файлом}

Read(F,X); {Прочитуються дані з файлу пов'язаного з файловою змінною F і заносяться в змінну Х}

Readln(F, X, Y, Z); {Послідовне зчитування трьох даних з файлу пов'язаного з файловою змінною F, і занесення їх значень в змінні X, Y і Z}

Виведення даних у файл процедура WRITE(<Файлова змінна>, <Об’єкт (Об'єкти) виведення>); або запис даних процедура WRITELN(<Файлова змінна>, <Об’єкт (Об'єкти) виведення>);

Приклади:

Assign(F,‘TextFill.TXT’); {встановлення зв’язку між файловою змінною та файлом}

Write(F,X); {Записується значення зміною Х у файл пов'язаний з файловою змінною F}

Writeln(F,X,Y Z); {Послідовний запис трьох даних X, Y, Z в файл пов'язаний з файловою змінною F}

При використанні процедур введення-виведення для роботи з файлами, на першому місці, в списку параметрів, повинна стояти файлова змінна. Якщо в цих процедурах опущена файлова змінна, то введення-виведення пов'язано із стандартними пристроями INPUT (КЛАВІАТУРА) при введенні даних (Read/Readln) або OUTPUT (ЕКРАН) при виведенні (Write/Writeln).

Зупинимося на істотних моментах при використовуванні операторів введення. Тип змінних при введенні з текстових файлів може бути тільки цілим, дійсним, символьним, рядковим або сумісним з ними. Складні структуровані типи (масиви, записи і т.п.) повинні бути введені поелементно. При введенні даних з текстового файлу необхідно пам'ятати правила читання значень в змінні із списку об'єктів, вказаних в операторах Read/Readln.

1) При читанні числових даних два числа вважаються різними (розділеними) якщо між ними стоїть проділ(и), символ(и) табуляції або символу кінця рядка.

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

3) При введенні рядків з текстових файлів, прочитується кількість символів рівна заявленій довжині рядка. Але якщо при зчитуванні трапляється символ #13, #10 або #26 читання рядка припиняється (може зчитуватися скорочений рядок).

4) При введенні числових даних роздільники (проділи, символи табуляції, символи кінця рядка чи файлу не зчитуються.

5) При введенні рядкових даних не зчитуються символи табуляції, символи кінця рядка чи файлу.

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

7) При використанні оператора Read(<>), дані зчитуються з поточного рядка файлу. І може виникнути ситуація, коли поточний покажчик зустріне символ кінець рядка, а читання через оператор Read продовжується. В цій ситуації читатися буде останній компонент файлу (можливо один і той же багато разів), до тих пір, поки не відбудеться перехід покажчика файлу на інший рядок.

8) При використанні оператора Readln(<>), відбувається зчитування даних з поточного рядка файлу і перехід покажчика файлу (після останнього зчитування) на початок наступного рядка, навіть якщо в поточному рядку залишилися не зчитані дані. Результатом виконання оператора Readln(<Файлова змінна>) без списку змінних для читання, є перехід покажчика файлу на початок наступного рядка у файлі.

9) В даний конкретний (поточний) момент зчитування читається той компонент файлу на який вказує покажчик файлу. Для пояснення вищезазначеного поняття звернемося до прикладів.

В нас сформований деякий текстовий файл ‘TextFill.TXT’ наступної структури, як показано на мал. 2. Зазначимо, що при перегляді на екрані він буде відображатися в звичайному вигляді мал. 2.



Приклад текст-файлу. 12 0.34

АБ -67 5 рядок символів

Мал. 2.

Як видно з малюнка 2 спецсимволи #13, #10 #26 на екрані не відображаються.

TextFill.TXT

поточний покажчик (ПОЗИЦІЯ 1)

поточний покажчик (ПОЗИЦІЯ 2)

поточний покажчик (ПОЗИЦІЯ 3)

поточний покажчик (ПОЗИЦІЯ 4)



1 рядок файлу Приклад текст-файлу. 12 0.34#13#10

поточний покажчик (ПОЗИЦІЯ 5)

поточний покажчик (ПОЗИЦІЯ 6)

поточний покажчик (ПОЗИЦІЯ 7)

поточний покажчик (ПОЗИЦІЯ 8)

поточний покажчик (ПОЗИЦІЯ 9)



2 рядок файлу АБ -67 5 рядок символів#13#10

                                                                           поточний покажчик (ПОЗИЦІЯ 10)



Кінець файлу #26

Мал. 3.

Розглянемо технологію введення даних з файлу ‘TextFill.TXT’ на прикладі фрагмента програми.

Var S:String[20]; D:String[15]; M,N,К:Integer;

X:Real; У,Z:Char; F:Text;

Begin

Assign(F,‘TextFill.TXT’);{Зв'язується файлова змінна F з файлом TextFill.TXT}

Reset(F); {Відкривається файл F для читання. Поточний покажчик встановлюється в початок першого рядка файлу і вказує на перший компонент для зчитування (на символ “П”). ПОЗИЦІЯ 1}

 Read(F,S); {Зчитується рядок завдовжки в 20 символів (включаючи проділ і крапку) і запам'ятовується в змінній S (S:=‘Приклад текст-файлу.’). Поточний покажчик файлу переміщується на наступний компонент файлу (на проділ). ПОЗИЦІЯ 2}

 Read(F,M); {Зчитується другий компонент файлу. Оскільки зчитується дані в змінну М числового типу, то рядок ‘12’ автоматично переводиться в число 12 і заноситься в змінну М (M:=12). Поточний покажчик переміщується на наступний компонент для зчитування (на проділ). ПОЗИЦІЯ 3}

Read(F,X); {Зчитується значення для змінної Х дійсного типу. Рядок ‘0.34’ переводиться в число 0.34 і заноситься в змінну Х (Х:=0.34). Поточний покажчик переміщується на символ кінця рядка. ПОЗИЦІЯ 4}

Readln(F); {Поточний покажчик переходить на початок наступного (другий) рядка файлу. ПОЗИЦІЯ 5}

Readln(F,У,Z,N,К,D); {Послідовно (згідно вказаного списку) зчитуються:  символ ‘A’ в змінну У (У:=‘A’). Поточний покажчик переміщується на наступний компонент (символ ‘Б’). ПОЗИЦІЯ 6 . Далі зчитується символ ‘Б’ в змінну Z (Z := ‘Б‘). Покажчик займає ПОЗИЦІЮ 7. Після цього зчитується значення для змінної N (N:= -67). Покажчик займає ПОЗИЦІЮ 8. Зчитується значення К (К:= 5). Після чого покажчик переміщується в ПОЗИЦІЮ 9. Потім  зчитується рядок D (D:=‘рядок символів’) і покажчик файлу переміщується на наступний рядок і вказує на ознака кінця файлу. ПОЗИЦІЯ 10}

Reset(F); {Файл F відкривається знову для читання (заздалегідь закрившись). Покажчик файлу займає початковий стан. ПОЗИЦІЯ 1}

Readln(F,D); {В змінну D заноситься рядок завдовжки в 15 символів (D:=‘Приклад текст-ф’). Поточний покажчик файлу займає ПОЗИЦІЮ 5}

Close(F); { Закривається файл F}

End.

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



TextFill.TXT

Поточний покажчик файлу. (ПОЗИЦІЯ 1)

Поточний покажчик файлу. (ПОЗИЦІЯ 2)

Поточний покажчик файлу. (ПОЗИЦІЯ 3)

 


 Приклад не коректної організації введення даних з файлу 23 44#13#10

 


 Компонент1 файлу

 Компонент2 файлу

 Компонент3 файлу

 Поточний покажчик файлу.(ПОЗИЦІЯ 4)



 Наступний рядок файлу#13#10

Мал. 4.

Розглянемо   приклад зчитування у файл F, інформації з файлу  TextFill.TXT на початку покажчик файлу займає ПОЗИЦІЮ 1 (мал.4).

Ми хочемо зчитати значення трьох компонент із поточного рядка файлу.

Проаналізуємо результати виконання наступного фрагмента програми:

VAR S : String[32];

X, Y : Integer;

F : Text;

Begin

Read(F,S); {Прочитується значення рядкової змінної S з файлу F (S:=‘Приклад не коректної організації’). Поточний покажчик файлу переміщується в ПОЗИЦІЮ 2}

Read(F,X,Y); {Прочитується значення числової змінної Х. Але покажчик вказує на рядковий (символьний) тип даних. Виникає помилка несумісності типів. Програма зупиняється або зависає, що призводить до неприємностей (наприклад втрата даних оскільки файл може залишитися не закритим}

End.

Розглянемо другу ситуацію з тим же файлом (мал. 4). Даний файл F, відкритого для читання, покажчик файлу займає ПОЗИЦІЮ 1. Ми хочемо зчитати значення трьох компонент із поточного рядка файлу. Зауважимо, що змінна S має тип String.

Проаналізуємо результати виконання наступного фрагмента програми:

VAR S : String;

X, Y : Integer;

F : Text;

Begin

Read(F,S); {Прочитується значення рядкової змінної S з файлу F. Оскільки змінна S має тип String (довжина рядка може бути до 256 символів), а при зчитуванні достроково зустрічається ознака кінця рядка, то на символі #13 зчитування значення S припиняється. (S:=‘Приклад некоректної організації введення даних з файлу 23 44’). Покажчик файлу в цій ситуації переміщується в ПОЗИЦІЮ 3}

Read(F,X,Y); {Зчитується значення числової змінної Х. Покажчик вказує на символ кінця рядка. Знову несумісності типів і результат виконання останньої операції непередбачуваний.}

End.

Розглянемо наступну ситуацію з тим же файлом (мал. 4). Файл F, відкритого для читання, покажчик файлу займає ПОЗИЦІЮ 1. Далі ми хочемо зчитати значення трьох компонент із поточного рядка файлу.

VAR S : String[10];

X, Y : Integer;

F : Text;

Begin

Readln(F,S); {Зчитується значення рядкової змінної S з файлу F. (S:=‘Приклад не’). Покажчик файлу в цій ситуації (після зчитування значення S) переміщується в ПОЗИЦІЮ 3 бо задіяний оператор Readln}

Read(F,X,Y); {Прочитується значення числової змінної Х. Але покажчик вказує на символьний (рядковий) тип даних. Знову виявляється помилка при зчитуванні даних з файлу}

End.

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

 TextFill.TXT

Рядок 1. Приклад раціональної структури файла#13#10

Рядок 2. 34 78 -6.89Е-3 45#13#10

Рядок 3 А Б В Г Д#13#10

Рядок 4 #26

Розглянемо вивід даних у файл. Тип змінних при записі в текстові файли може бути (як і при читанні з файлу) тільки цілим, дійсним, символьним, рядковим або сумісним з ними. Складні структуровані типи (масиви, записи і т.п.) виводяться поелементно. При виведенні даних в текстовий файл необхідно пам'ятати правила запису об'єктів або списків об'єктів виведення, вказаних в операторах Write/Writeln/.

1) Процедура WRITE(<>) виводить (записує) дані в поточний рядок (на який вказує поточний покажчик файлу) і не закриває його. Тобто наступні дані будуть виводиться в цей же рядок. Після запису даних покажчик файлу переміщується в позицію, безпосередньо наступну за записаним об'єктом (в цьому ж рядку).

2) Процедура WRITELN(<>) виводить (записує) дані в поточний рядок і після запису об'єкту (списку об'єктів) виведення, закриває рядок (ставить в кінці поточного рядка ознаку кінця рядка і переміщує поточний покажчик файлу в початок наступного рядка файлу.

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

4) Процедура WRITELN(<>) без об'єктів виведення переміщає покажчик файлу в початок наступного рядка (вставляє порожній рядок у файл).

5) Список об'єктів виведення може містити константи, змінні, вирази – лише б вони мали відповідні типи і були розділені комами.

6) Все що стоїть в лапках або належить до рядкових (символьним) типів даних, виводиться в файл в тому вигляді, в якому представлено.

7) При виведенні цілочислових даних, спочатку виводиться проділ або знак числа, а потім саме число.

8) При виведенні дійсних чисел – спочатку виводиться проділ або знак числа, а потім саме число в експоненціальній формі. Тобто числові дані виводяться розділеними.

9) При виведенні даних у файл є можливість керувати форматом виведення даних. Вимоги до формату тіж, що і при виведенні на екран.

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


Приклад виведення даних у файл




Результати контрольних робіт

Учня

Іванова Івана Івановича



Математика

Фізика

Інформатика

Історія

5

5

4

3



Інша інформація

 2.34 -2.3Е-2 – 345.78

Мал. 5.

Проаналізуємо роботу наведеної нижче програми ілюстрація роботи якої зображена на мал. 6.

TextFill.TXT

поточний покажчик ПОЗИЦІЯ 1

ПРИКЛАД ВИСНОВКУ ДАНИХ У ФАЙЛ#13#10

поточний покажчик ПОЗИЦІЯ 2

#13#10

поточний покажчик ПОЗИЦІЯ 3

Результати контрольних робіт#13#10

поточний покажчик ПОЗИЦІЯ 4

Учня#13#10

поточний покажчик ПОЗИЦІЯ 5

Іванов Іван Іванович #13#10

поточний покажчик ПОЗИЦІЯ 6

#13#10

поточний покажчик ПОЗИЦІЯ 7

Математика Фізика Інформатика Історія #13#10

поточний покажчик ПОЗИЦІЯ 8

поточний покажчик ПОЗИЦІЯ 9

поточний покажчик ПОЗИЦІЯ 10

поточний покажчик ПОЗИЦІЯ 11

5                 5                 4                 3 #13#10

поточний покажчик ПОЗИЦІЯ 12

#13#10

поточний покажчик ПОЗИЦІЯ 13

Інша інформація #13#10

поточний покажчик. ПОЗИЦІЯ 14

 поточний покажчик. ПОЗИЦІЯ 15

0.234 – 2.3E-2 – 345.78#13#10

поточний покажчик. ПОЗИЦІЯ 16

#26

TextFill.TXT

Поточний покажчик

#26

Мал. 6.

Program PRIMER;

Uses CRT;

VAR F:Text; S:String;

А, B, С, D : Byte; X, Y, Z:Real;

Begin

Assign(F,‘TextFill.TXT’ ); {Зв’язування  логічного файлу з фізичним}

Rewrite(F); {Відкривається порожній файл . Поточний покажчик у позиції 1}

Writeln(F,‘Приклад виведення даних у файл’:55); {В рядку для виведення 30 символів. Задаємо формат виведення ((80–30))div2+30=55. Вказаний рядок записується в файл F у вказаному форматі. Далі вставляється порожній рядок і покажчик файлу переміщується в початок цього порожнього рядка.}

Writеln(F); {Вставляється порожній рядок. Покажчик файлу переміщується в початок наступного рядка. ПОЗИЦІЯ 3}

S:=‘Результати контрольних робіт’;

Writeln(F,S:54); {Виводиться рядок S у форматі 54=((80–28)div2)+28 починаючи з позицієї, на яку вказує покажчик файлу. Після запису рядка S у файл, покажчик переміщується на наступний рядок. ПОЗИЦІЯ 4}

Writeln(F,‘Учня :42); {Записується у файл F вказаний рядок для висновку у форматі 42=((80–4)div2)+4. Покажчик файлу переміщується на рядок нижче. ПОЗИЦІЯ 5}

S:= ‘Іванов Іван Іванович’;

Writeln(F,S:45); {Записується у файл F рядок S у форматі 45=((80–20)div2)+20. Покажчик файлу переміщується на рядок нижче. ПОЗИЦІЯ 6}

Writeln(F); {До файлу F додається порожній рядок. Покажчик файлу переміщується на рядок нижче ПОЗИЦІЯ 7}

S:= ‘ Математика Фізика Інформатика Історія’;

Writeln(F,S:58); {Записується у файл F рядок S у форматі 58=((80–37)div2)+37. Покажчик файлу переміщується на рядок нижче ПОЗИЦІЯ 8}

А:= 5; B:= 5; С:= 4; D:= 3;

Writeln(F,А:26,B:9,С:8,D:9); {Записуються у файл F значення цілих чисел А, B, С і D у відповідних форматах. Підрахуємо формат для значення А. Значення А повинне потрапити під 5-у цифру слова “Математика”. Запис цього слова почалася з 21 позиції. 21+5=26. Формат для А рівний 26. Формат для В: значення В повинне потрапити, наприклад, під букву “и” слова “Фізика”. Але значення А стоїть вже під буквою “м” (в середині слова “Математика”). Від цієї букви до букви “и” 9 позицій. Формат для значення В рівний 9. Аналогічно обчислюється формат для С і D. Після виведення кожного значення А, B, С і D покажчик файлу переміщується в поточному рядку виведення на наступну позицію, безпосередньо за виведеною інформацією. Після виведення списку вказаних змінних (А, B, С, D) покажчик файлу переміщується на рядок нижче ПОЗИЦІЯ 12}

Writeln(F); {Вставляється наступний порожній рядок. Поточний покажчик файлу переміщується в ПОЗИЦІЮ 13}

Writeln(F,‘Інша інформація); {Виводиться рядок вказаний в операторі Writeln і поточний покажчик переводиться в ПОЗИЦІЮ 14}

X:= 0.234;

Write(F,X:5:3); {Виводиться дійсне значення Х у форматі 6:3. Перед числом, що виводиться, вставляється проділ. Поточний покажчик файлу переміщується на наступний компонент для запису в цьому ж рядку ПОЗИЦІЯ 15}

Y:= – 2 . 3; Z := – 245. 78;

Write(F,Y,Z:7:2); {Виводяться дійсне значення Y (в експоненціальному вигляді) і Z (у форматі 7:2). Перед числами, що виводяться проділи не вставляються. Роздільниками служать знаки “– чисел, що виводяться . Після виведення всього списку, поточний покажчик файлу переміщується на наступний рядок в ПОЗИЦІЮ 16}

Close(F); {Закривається файл F}

Rewrite(F); {Повторно відкривається файл F (знову порожній) для запису.}

Сlose(F); {Закривається файл F}

End.

Немає коментарів:

Дописати коментар