ПАСКАЛЬ: ОБРОБКА ТЕКСТІВ
ПОШУКОВА РОБОТА
1. Особливості організації текстів
У мові Турбо Паскаль для подання текстів на зовнішніх носіях означено спеціальний тип файлів з ім’ ям TEXT. Файли цього типу будемо називати файлами-текстами.
Елементами файлів-текстів є символи, але тип text відрізняється від типу fileof char наявністю спеціальнихпідпрограм, пов’ язаних саме з розбиттям на рядки. Розглянемо деякі з цих підпрограм.
Спосіб, у який задається кінець рядка фізичного файла, залежить від файлової системи, і можна навіть його й не знати. Достатньо розглядати рядок файлової змінної як послідовність, що закінчується спеціальним символом. Він позначається словом eol. Рядок, складений лише цим символом, називається порожнім.
Слова eol немає в мові Паскаль, і в програмах воно не вживається.
Визначити, чи доступний кінець рядка eol у файлі під час виконання програми, можна за допомогою функції EOLN. З виклику
eoln(f)
повертається значення true, якщо доступний eol, і false у противному разі. У системі Турбо Паскаль ця функція повертає значення true, коли доступним є символ chr(13). Цей символ, власне, й задає кінець рядка. У текстах, створених "під DOS", за цим символом, як правило, іде chr(10), що позначає "переведення рядка". Позначимо ці символи як [13] і [10]. Ось приклад тексту, який говорить сам за себе:
ЦЕЙ ТЕКСТ[13][10]СКЛАДАЄТЬСЯ[13][10][13][10]
З П’ЯТИ РЯДКІВ,[13][10]З ЯКИХ ТРЕТІЙ ПОРОЖНІЙ[13][10]
Звичайно, приємніше читати цю послідовність у вигляді
ЦЕЙ ТЕКСТ[13][10]
СКЛАДАЄТЬСЯ[13][10]
[13][10]
З П’ЯТИ РЯДКІВ,[13][10]
З ЯКИХ ТРЕТІЙ ПОРОЖНІЙ[13][10]
Для визначення, чи прочитано текст, викликається функція EOF. У текстах, на відміну від типізованих файлів, ознака кінця файла може задаватися не лише засобами операційної системи, але й спеціальними символами в самому фізичному файлі. Для програм, написаних мовою Турбо Паскаль, таким символом є chr(26). Наприклад, наведений текст у фізичному файлі насправді закінчувався б не символами [13][10], а [13][10][26]. Якщо в тексті доступний символ chr(26), то з виклику функції eof(f) повертається true, за іншого символу – false.
Ім’ я input можна не вказувати у викликах та замість eof(input) чи eoln(input) писати eof чи eoln.
2. Записування в текст
Описання роботи з текстами, що є файлами на диску комп’ ютера, почнемо з записування, оскільки воно має набагато менше "підводних каменів", ніж читання.
Нехай далі f є ім’ ям файлової змінної типу text. Текст, як і файли інших видів, установлюється в початковий стан для запису викликом rewrite(f). Після цього файл стає порожнім. Для того, щоб дописувати до вже існуючого тексту, треба установити його в початковий стан для дописування викликом процедури APPEND:
append(f).
Після цього всі символи тексту, крім символу кінця файла, залишаються в тексті, і нові символи будуть дописуватися за останнім із них.
Запис у текст задається викликами процедур WRITE і WRITELN, першим аргументом у яких є ім’ я файлової змінної. При виконанні виклику
write(f, вираз-базового-типу-або-рядок)
спочатку обчислюється значення виразу. За цим значенням створюється послідовність символів, що його зображає, і копіюється в текст f. Наприклад, виклик
write(f, trunc( sqrt(9999) ) )
задає дописування в файл двох символів '9' і '9', що задають число 99.
У виклику можна записати одразу кілька виразів через кому:
write(f, вираз1, вираз2, ...).
Наприклад, за x=2 виклик
write(f, 'x=', x, '; x**2=', sqr(x))
задає виведення в файл послідовності символів x=2; x**2=4. До речі, такий виклик виконується як послідовність викликів
write(f, вираз1); write(f, вираз2); ...
Процедура writeln відрізняється лише тим, що за виклику
writeln(f, список-виразів-базових-типів-або-рядків)
за останньою сталою в текст додається eol (у Турбо Паскаль – [13][10]). Список виразів тут може бути порожнім – тоді лише додається eol.
У викликах процедур write і writeln після виразу через двокрапку можна задати ширину поляWпід запис значення виразу, наприклад,
write(f, sqr(x):2).
Тут W=2. Нехай для запису значення виразу потрібно L символів. В останньому виклику L=1 за x<4, L=2 за 3<x<10, L=3 за 9<x<34 тощо. Якщо L£ W, то перед символами значення додаються W- L пропусків; а якщо L> W, то виводяться всі символи. Таким чином, за x=3 друкується пропуск і 9, а за x=100 – всі п’ ять символів 10000.
Після виразу дійсного типу можна також указати кількість N цифр дробової частини, що виводяться після десяткової крапки, наприклад,
write(f, sqrt(x): 7 : 3).
Якщо N указано, то виводиться стала з фіксованою крапкою та N цифрами після крапки, інакше – нормалізована з порядком. В даному разі за x=2 виводиться два пропуски та 1.414. Остання цифра є результатом округлення. Деякі інші деталі можуть визначатися системою програмування.
Приклад 1. За виклику
writeln (f, 'СЛОН', 'собака':1, 'кіт':5)
у текст виводиться рядок
С | Л | О | Н | с | о | б | а | к | а | к | і | т | [13] | [10] |
за виклику
write (f,1.1239:1:3, 0.11234567 :21)
– символи
1 | . | 1 | 2 | 4 | 1 | . | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 0 | 0 | 0 | 0 | E | - | 0 | 0 | 0 | 1 |
за виклику
writeln (f, 123.499999:1:0,-12345.1234567:12)
– рядок
1 | 2 | 3 | - | 1 | . | 2 | E | + | 0 | 0 | 0 | 4 | [13] | [10] |
Приклад 2. Створити текст можна буквально "власними руками", набираючи його рядки на клавіатурі у відповідь на запрошення при виконанні такої програми:
program creatext ( input, output );
var f:text; s: string;
begin
assign(f, 'myfile.txt'); rewrite(f);
writeln ( 'Наберіть символи рядка й натисніть Enter:' );
whilenot eof ( input ) do
begin
readln( s ); writeln (f, s );
writeln ( ' Наберіть символи рядка й натисніть Enter:' );
end;
close(f)
end.
Для задання кінця тексту на клавіатурі треба замість набирання чергового рядка натиснути на Ctrl-Z. І не забути про Enter.
Зазначимо, що при закриванні тексту за процедурою close до нього додається символ кінця chr(26).
Задачі
1. Переробити програму з прикладу 14.2 так, щоб спочатку з клавіатури задавалося ім’ я створюваного файла.
2. Створити текст із табличкою степенів числа 2 від 1 до
а) 30 (скористатися змінними типу Longint);
б) 63 (скористатися змінними типу Compound).
3. Читання числових сталих із тексту
Тут ми розглянемо читання з тексту лише числових сталих, оскільки символи та рядки читаються зовсім інакше.
Для читання числових сталих зручно скористатися процедурою READ – їївиконання в разі читання текстів цілком відрізняється від читання типізованих файлів. Її виклик, як і для читання типізованих файлів, має вигляд
read(f, список-імен-змінних),
де f – ім’ я тексту, а змінні мають числові типи. Для безпомилкового виконання виклику файл повинен містити послідовність сталих, типи яких відповідають типам змінних списку.
Ціластала – це послідовність цифр, можливо, зі знаком '+' чи '-' на початку, яка задає ціле число з носія відповідного цілого типу, причому між знаком та першою цифрою в тексті не може бути пропусків. Дійснастала – це послідовність цифр та інших символів із структурою сталих мови Паскаль, наприклад, 1.1, 2., .99, 1e-3, -2.73E+02. Кожна ціла стала також може розглядатися як дійсна.
Числові сталі в текстах відокремлюються пропусками в довільній кількості. Символи табуляції та кінця рядка також будемо називати пропусками.
Виклик read(f, X) за цілого чи дійсного x виконується так. З тексту читаються пропуски, а за ними символи сталої до найближчого пропуска. Доступним після читання сталої буде перший пропуск за нею. Якщо символи справді утворюють сталу відповідного типу, то за ними обчислюється значення й присвоюється змінній. За дійсного X у тексті може бути й ціла стала – за нею обчислюється відповідне дійсне значення. Наприклад, за цілою сталою 99 дійсне значення 99.0.
Символи можуть не утворювати сталої відповідного типу – тоді виникає помилкова ситуація й виконання програми аварійно завершується. Наприклад, помилковими є послідовності символів - 2 (тут пропуск між знаком і цифрою), 12345m або 123- (присутні нецифрові символи там, де їх не може бути), або 13., коли читається значення цілої змінної.
Зазначимо, що системи програмування забезпечують засоби обробки помилкових ситуацій та запобігання аварійного закінчення. Але ми цього тут не висвітлюємо.
Система програмування Турбо Паскаль має таку особливість. Якщо доступний кінець файла, то спроба читати число не завершується аварійно, а відповідна змінна набуває значення 0!
Читання сталих базових типів за процедурою READLN аналогічне процедурі read. Відмінність її в тім, що після читання останньої сталої всі символи тексту, що залишилися до найближчого eol, пропускаються разом із ним. Доступним стає перший символ наступного рядка тексту. Список імен змінних може бути порожнім; у такому разі виклик readln(f) задає пропуск, тобто читання без зберігання, поточного рядка тексту.
Приклад. У тексті записано такі символи:
1 | 2 | 3 | [13] | [10] |
5 | 5 | [26] |
Нехай x, y, z, t – цілі змінні. Читання read(f, x, y); read(f, z, t) надасть їм значень 1, 2, 3, 55 відповідно, читання readln(f, x, y); read(f, z, t) – 1, 2, 55, 0, читання readln(f, x); readln(f, y, z, t) – 1, 55, 0, 0.