WWW.REFERATCENTRAL.ORG.UA - Я ТУТ НАВЧАЮСЬ

... відкритий, безкоштовний архів рефератів, курсових, дипломних робіт

ГоловнаІнформатика, Компютерні науки → Обробка текстів - Реферат

Обробка текстів - Реферат

що ми вже потрапили в коментар, і попередню дужку копіювати не треба. За іншого символу попередня дужка разом із новим символом копіюється, і ми залишаємося зовні коментаря.
3. Якщо ми потрапили в коментар, то символ '*' може означати, але не обов' язково, "початок закінчення" коментаря (наступний випадок). Всі інші символи, в тому числі й ')', ніяк не обробляються.
4. Перед цим у коментарі була прочитана '*', тобто коментар, можливо, починає закінчуватися. Нова '*' означає новий "початок кінця" коментаря. Символ ')' означає, що коментар закінчено, а будь-який інший - що коментар продовжується.
Введемо поняття "стан тексту після останнього прочитаного символу". У нашому випадку такими станами є "зовні коментаря", "початок коментаря", "всередині коментаря", та "початок кінця коментаря". Стан тексту цілком визначається тим станом, який був раніше, та останнім символом. Пункти 1-4 описують обробку символів, відповідну цим станам, а також зміни стану.
Позначимо вказані стани відповідно словами out (зовні), bgn (початок), incm (всередині коментаря), bgend (початок кінця). Значенням останнього прочитаного символу ch може бути '(', '*', ')' або інший символ. Подамо дії, описані в пунктах 1-4, у вигляді таблиці на рис.14.1. Стовпці відмічено символами, рядки - станами. У клітині на перетині рядка й стовпця вказано зміну стану та інші дії, відповідні цим стану й останньому символу. Зміна станів подається присвоюванням, відсутність якого означає, що стан не міняється.
Зміст таблиці подамо також у вигляді діаграми станів (рис.14.2). Стрілки показують зміну станів залежно від останнього прочитаного символу. Кожну стрілку відмічено дробом: угорі вказано символ, унизу - його обробку. Символ позначає довільний символ, відмінний від '(' , - відмінний від '(' та '*', - від '*' та ')'.
Початковим станом тексту природньо вважати out. Копіювання тексту з вилученням коментарів можна імітувати пересуванням по діаграмі та виконанням дій, указаних на стрілках. На кожному кроці імітації читається черговий символ тексту і згідно діаграми за ним та поточним станом визначаються дії та зміна стану.
За наведеними таблицею чи діаграмою неважко побудувати програму копіювання тексту з вилученням коментарів. У програмі переписано зміст таблиці за допомогою case-операторів. Нехай змінна ch зберігає останній прочитаний символ, а g є ім' ям тексту-копії. Означимо тип-перелік станів:
type States=(out, bgn, incm, bgend)
та змінну q цього типу. Спочатку q:=out. А далі
while not eof(f) do
begin
read(f, ch);
case q of
out: case ch of
'(': q:=bgn
else write(g, ch)
end;
bgn: case ch of
'(': write(g, '(');
'*': q:=incm
else
begin
write(g, '(', ch); q:=out
end;
end;
incm: case ch of
'*': q:=bgend
end;
bgend: case ch of
'*': ;
')': q:=out
else q:=incm
end;
end; {case q of}
end; {while not eof(f) }
Як бачимо, виконання наведеного циклу відповідає описаній вище імітації діаграми. Оформлення програми залишаємо вправою.Р
7. Використання рядків для виведення в текст
Приклад 9. Редактор Word символом chr(13) задає розбиття текстів не на рядки, а на абзаци. З точки зору редактора ДОС або Турбо Паскаль такий абзац є рядком, причому, як правило, дуже довгим, і читати його незручно. Напишемо програму копіювання тексту з довгими рядками в текст із рядками довжини не більше ніж, наприклад, 80.
Уточнення. Пропуски, кінці рядків і символи табуляції будемо називати пропусками. Можна вважати, що послідовності символів, відмінних від пропусків, у тексті, тобто слова, мають довжину не більше 80. Слова в тексті відокремлюються пропусками в довільній кількості. У новому тексті між словами рядка повинен бути один пропуск, тобто текст має ущільнюватися.
У загальному вигляді розв' язання задачі полягає в тім, що з тексту по одному "витягуються слова" й записуються в новий текст.
Якщо читання слова задати функцією getlex, яка повертає ознаку наявності слова, а запис слова - процедурою putlex, то головним у програмі буде цикл вигляду
while getlex do putlex.
Отже, прочитане слово треба записати в новий текст. Але замість цього запишемо його в допоміжний рядок довжини 80, який назвемо "рядок слів".
Слова накопичуються в рядку слів, і коли чергове слово вже не вміщається в ньому, він записується окремим рядком у текст за допомогою процедури writeln. Після цього нове слово записується в рядок слів із його початку. Наприкінці, коли початковий текст уже прочитано, треба не забути переписати рядок слів у новий текст.
Наведений алгоритм уточнюється далі у вигляді процедури putlex.
Для того, щоб "витягнути" слово з тексту, треба прочитати пропуски й накопичити в рядку-слові символи-непропуски, що йдуть поспіль до наступного пропуска або до кінця тексту.
Серед пропусків, що читаються, можуть бути кінці рядків. Перший із них означає, що треба переписати накопичений рядок слів у новий текст, а всі інші - що записати порожній рядок. І тільки після цього записувати нове слово з початку рядка слів. Таким чином, читаючи пропуски, треба підраховувати кінці рядків.
Нехай str - це ім' я типу string[80]. Читання чергового слова уточнимо у вигляді наступної функції getlex. Символами-пропусками у ній вважаються символи табуляції chr(9), переведення рядка chr(10), нового рядка chr(13) і власне пропуск chr(32). Її останній параметр nume зберігає кількість кінців рядків, що передували знайденому слову. Ця кількість використовується на початку виконання процедури putlex.
function getlex(var f : text; var lex : str; var nume : integer) : boolean;
const empsym : set of char=[chr(9), chr(10), chr(13), chr(32)];
var c : char; inlex : boolean;
begin
lex:=''; inlex:=false; nume:=0;
while not eof(f) and not inlex do
begin
if eoln(f) then
begin inc(nume); readln(f) end
else
begin read(f, c); inlex:=not (c in empsym) end;
end;
while inlex do
begin
lex:=lex+c;
if not eof(f) then
begin
if eoln(f) then inlex:=false
else begin read(f, c); inlex:=not (c in empsym) end;
end
else inlex:=false
end;
getlex:=(lex'');
end;
Запис накопиченого рядка слів (глобальна змінна з ім' ям buff) у текст задамо такою процедурою:
procedure outbuff(var f : text);
begin
writeln(f, buff); buff:=''; bp:=1;
end;
Як уже зазначалося, запис слова в рядок слів задається процедурою putlex:
procedure putlex(var f : text; lex : str; nume : integer);
var llx, k : integer;
begin
if nume > 0 then
outbuff(f);
for k:=1 to nume-1 do
writeln(f);
llx:=length(lex);
if (bp>1) and (bp+llx>mx) then
outbuff(f)
else
if buff'' then
begin
buff:=buff+' '; bp:=bp+1;
end;
buff:=buff+lex; bp:=bp+llx;
end;
Нарешті, програма копіювання тексту з перетворенням рядків має вигляд:
program f80;
const mx=80;
type str=string[mx];
var f, g : text;
const buff : str=''; bp : integer=1;
var lex : str; nume : integer;
function getlex(var f : text; var lex : str; var nume : integer):boolean;
...
end;
procedure outbuff(var f : text);
...
end;
procedure putlex(var f : text; lex : str; nume : integer);
...
end;
begin
assign(f, 'in.txt'); assign(g, 'out.txt');
reset(f); rewrite(g);
while getlex(f, lex, nume) do
putlex(g, lex, nume);
if buff'' then outbuff(g);
close(f); close(g);
end.
Loading...

 
 

Цікаве