Робота з файлами (Паскаль та Бейсік), Відкритий клас

Назва документа: Любутов О.Д. Вирішення олімпіадних завдань

Анотація: Олімпіадні завдання з програмування

Робота з файлами

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

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

Будь-який існуючий файл можна відкрити як файл прямого доступу або як послідовного.

Файлпослідовного доступускладається (має складатися) з рядків (кілька байтів) які закінчуються спеціальною ознакою (зазвичай це символи повернення каретки і перекладу рядка, їх ASCIIкоды 13 і 10).

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

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

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

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

Для роботи з файлом його потрібно «відкрити», а по закінченні роботи «закрити». Для цього в бейсику існують оператори OPEN і CLOSE. Ось їх формат:

- це шлях та ім'я файлу (якщо шлях не вказаний, то програма шукатиме файл у папці, звідки запущено проект або відкомпільована програма)

- одне із зарезервованих слів:

INPUT – існуючий файл відкривається для читання. Необхідно, щоб файл із таким ім'ям існував.

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

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

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

Між операторами OPEN і CLOSE ми можемо працювати з відкритим файлом. Читати з нього, писати чи дописувати до нього. Ось як це реалізується. Допусти ми хочемо створити файл proba.txt в корені на диску C. І записати в нього перший двовірш вірша Некрасова і числа від 1 до 10.

DIM S as string, I as integer

OPEN “C:\proba.txt” FOR OUTPUT AS #1

S=”Одного разу, в зимову студію”

PRINT #1, "Я з лісу";

PRINT #1, "вийшов, був сильний мороз"

IF I ) повертає логічне значення True, якщо досягнуто кінець файлу. Наприклад, нам потрібно вивести на екран весь вміст текстового файлу:

DIM S as string

OPEN “C:\proba.txt” FOR INPUT AS #1

DO WHILE NOT EOF(1)

Про файли послідовного доступу, мабуть, все.

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

Реалізується це так:

Open "C:\proba.txt" For Random As #1 Len = 2

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

Читання та запис здійснюється спеціальними операторами:

Номер запису у бейсику починається з одиниці.

І завершується робота із файлом оператором CLOSE #1

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

FileVar:file ofтип ;

var F: File of byte;

Для переміщення записів у паскалі використовується процедураseek( , ). У паскалі записи починаються з нульового запису.

Решта відбувається так само як з текстовими файлами.

Потрібно зв'язати файлову змінну з конкретним файлом:

Assign(F, 'З :\proba.txt');

Потім відкрити файл:

Тепер можна прочитати з файлу 20 символів, починаючи з 25 символу і вивести їх на екран:

for i:= 25 to 44 do

І не забудемо закрити файл:

А тепер спробуємо розглянути олімпіадну задачу, де було задано файл з 999999 чисел, що не перевищують за модулем 1000000000 (по 4 байти на число). Потрібно було знайтимедіану цього числового масиву. Медіаною масиву називається число, розташоване в середині впорядкованого масиву. У нашому випадку медіаною буде значення 500 000 елемента в упорядкованому масиві.

Так як завдання реалізовувалася DOS-івськими мовами програмування (BP 7.0 QB і т.д.), де обсяг пам'яті обмежений 64Кб ​​(якщо не використовувати динамічну пам'ять), то зрозуміло, що розмістити весь файл в оперативній пам'яті (4Мб) не представляється можливим . Можна придумати багато різних способів розв'язання цієї задачі, і залежно від продуктивності комп'ютера вони або покладуться в обмеження часу виконання (30 секунд), або ні. Але найбільш оптимальним способом вирішення цього завдання буде робота з даними у файлі.

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

Ми хочемо знайти «посадкове місце» першого елемента нашого масиву