REFERATUA.ORG.UA — База українських рефератів




ch}

write(ch)

end;

close(f);

readln;

end.

За її виконання на екрані буде надруковано лише abc. Справа в тім, що після того, як прочитано символ c, доступним стає chr(26). Далі виконується виклик eof(f), з нього повертається значення true, і виконання циклу закінчується.

Якщо X рядкового типу, то при виконанні виклику read(f, X) символи до найближчого eol читаються та присвоюються елементам X; доступним стає eol, тобто chr(13) в системі Турбо Паскаль. Якщо символів тексту до eol більше, ніж уміщається в X, то X заповнюється до кінця, і доступним стає перший символ за тими, що прочитано в X.

Якщо перед читанням рядка X доступний eol, то він залишається доступним, а значенням X стає порожній рядок. Ось чому ми рекомендуємо не застосовувати процедуру read при читанні рядків.

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

whilenot eof(f) do

begin

read (f, x); {???}

обробка x

end,

де x – змінна-рядок, читаються лише символи першого рядка тексту, після чого кінець рядка залишається доступним "назавжди". Цикл собі виконується, комп' ютер "висить", а користувач програми починає нервувати й лаятися.

Коли при читанні рядка доступний кінець тексту, він аналогічно залишається доступним, а змінній-рядку присвоюється значення '' (порожній рядок).

Читання символів і рядків за процедурою readln аналогічне процедурі read, але після читання символів решта рядка тексту пропускається, тобто доступним стає символ, наступний за найближчим eol. Радимо задавати читання рядків за допомогою процедури readln.

Список імен змінних у виклику може бути порожнім; у такому разі при виклику readln(f) пропускається поточний рядок тексту.

Приклад 4. Нехай діють означення

f : text; c1, c2 : char; s1, s2 : string[4],

а eol явно позначає кінець рядка в тексті, з яким зв' язано f:

t

r

u

e

eol

f

a

l

s

e

eol

eol

Після виклику

read (f, c1, c2, s1, s2 )

змінні набудуть значень: c1=' ', c2='t', s1='rue' та s2=''; доступним буде перший із указаних eol. Якщо далі виконати read(f, c1, c2), то значеннями с1 і c2 будуть chr(13) і chr(10), а доступним стане символ f.

За такого самого тексту виклик

readln (f, s1, c1, c2, s2 )

надає змінним значень s1=' tru', c1='e', c2=chr(13), s2=chr(10)+'fal'. Символи 's' і 'e' пропускаються, і доступним стає третій eol, тобто chr(13).

5. Читання тексту з рядками обмеженої довжини

У багатьох текстах довжина рядків неоднакова, але обмежена, як правило, числом, що не перевищує 255 – максимальну довжину рядків типу string. Використання змінних цього типу дозволяє дуже просто описувати читання текстів.

Алгоритми розв' язання задач із обробки таких текстів часто мають загальний вигляд

whilenot eof(f) do

begin

readln(f, s); {s має тип string}

обробка рядка s;

end.

Приклад 5. Написати процедуру копіювання тексту за умови, що рядки тексту мають довжину не більше 80, а рядки порожні або такі, що містять лише пpопуски, не копіюються.

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

procedure cpnonemp(var f, g : text);

var s : string[80];

k : integer; emp : boolean;

begin

whilenot eof(f) do

begin

readln(f, s); k:=1; emp:=true;

while (k<= length(s)) and emp do

if s[k]<>' ' then emp:=false

else k:=k+1;

ifnot emp then writeln(g, s)

end

end;

6. Посимвольне читання тексту

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

Для розв' язання задачі треба

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

Слово є лексичноюодиницею, або лексемою тексту, тобто такою послідовністю, що має самостійне значення, тому функцію читання слова з тексту назвемо getlex (взяти лексему). Ось її заголовок:

function getlex(var f:text; var lex:string):boolean.

З її виклику повертається ознака наявності слова в частині тексту, прочитаній за її виклику. Слово зберігається як значення параметра-змінної lex (лексема), а коли його в решті тексту немає, значенням стає порожній рядок. Отже, нехай s1, s2 – рядки, nrep – лічильник повторень у такому алгоритмі:

nrep:=0;

if getlex(f, s1) then

begin

while getlex(f, s2) do

if s1=s2 then nrep:=nrep+1;

writeln(nrep)

end

else writeln('у тексті немає слів');

Щоб прочитати слово, треба

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

Для визначення, чи є символ латинською літерою, скористаємося функцією isletter:

function isletter(c : char) : boolean;

begin

isletter := ('a'and (c<'z') or ('A'and (c<'Z')

end;

Запишемо функцію getlex. Коли під час її виклику завершується виконання першого циклу, можуть бути істинними обидві умови, eof(f) та isletter(ch). Це можливо, якщо останній символ тексту є водночас першою літерою слова. У цьому разі символ дописується до порожнього слова.

function getlex(var f : text; var lex : string) : boolean;

var ch : char; isl : boolean;

begin

ch:=' '; lex:=''; getlex:=false;

whilenot eof(f) andnot isletter(ch) do

read(f, ch);

{eof(f) or isletter(ch)}

if isletter(ch) then

begin {створення рядка-лексеми}

getlex:=true; lex:=lex+ch;


 
Загрузка...