8525 Паскаль. P.34. Текстовые редакторы. Сборник задач по программированию Александра Приходько
 

Сборник задач по программированию. Старая версия

 

 Приходько А. Н.

 

клиент, процедура, xslt, сервлет, html, java, по программированию, сервлет, applet, класс
 

Паскаль. P.34. Текстовые редакторы

Этот параграф будет посвящен демонстрации принципов работы текстовых редакторов посредством написания их на языке Паскаль. Как вы знаете, текстовые редакторы являются наиболее используемыми компьютерными программами и предназначены для корректировки содержимого текстовых файлов. Текстовый файл это файл, компонентами которого являются символы (значения из типа Char). То есть, текстовый файл это file of char. Иногда, текстовый файл описывают как file of string. В языке Паскаль также имеется встроенный тип текстового файла - f : text.

Разберемся в отличиях этих 3-х типов файлов.

Текстовый файл предназначен для хранения каких-то текстов. Текст это набор страниц. Каждая страница это набор символьных строк. Каждая символьная строка это набор символов.

File of char - непрерывная последовательность символов. Строки не отделяются друг от друга или отделяются с помощью специальных символов chr($0A) и chr($0D). Если строки не отделяются друг от друга, то при выводе на экран дисплея переход на следующую строку происходит естественным путем при заполнении предыдущей строки (80 символов). Если строка содержит меньше 80 символов, то недостающие позиции заполняются пробелами. Если строки отделяются друг от друга, то переход на следующую строку осуществляется символами chr($0A) - на одну строку вниз и chr($0d) - возврат на начало строки. В этом случае, для хранения строки в файле используется ровно столько символов сколько нужно + 2. Чтение и запись в файл идет только посимвольно (read и write). Нужно самим управлять концами строк.

File of string - последовательность строк. Строки отделяются символами chr($0A) и chr($0D). Неэкономный режим. Для одной строки отводится 256+2 байта, даже если она содержит всего 3 символа. Хотя внешне все удобно как в "Text". Можно использовать операторы Readln и Writeln для чтения и записи строк.

Text - внутри представлен как file of char с отделением строк, но позволяет использовать Readln и Writeln. Данное представление считается стандартным.

Наш текстовый редактор будем писать поэтапно. Сначала напишем программу перемещения курсора по экрану дисплея. (Смотрите задачу ). Внесем в нее некоторые дополнения с целью получения программы набора символов на экране дисплея. То есть, эта программа должна теперь не только реагировать на нажатие клавиш "вверх", "вниз", "вправо" и "влево" и соответственно перемещать курсор, но и на нажатие цифро-буквенных клавиш и отображать эти символы в том месте где находится курсор при нажатии клавиши. Для этого, ничего не меняя в программе, добавим внутрь цикла Repeat.. Until еще одну обработку - следующий оператор if.

if (lo(r.ax)<>0) and (lo(r.ax)<>8) and (lo(r.ax)<>13) and
    (lo(r.ax)<>27) then begin
        ch:=chr(lo(r.ax));
        write(ch);
end;

В результате мы получим следующую программу.

program AA;
uses crt, dos;
var
    r : registers;
    x, y : integer;
    ch : char;
begin
    clrscr;    x:=1;    y:=1;
    repeat
        r.ax:=$0000; Intr($16,r);
        if (lo(r.ax)=0) and (hi(r.ax)=72) and (y>1) then y:=y-1;
        if (lo(r.ax)=0) and (hi(r.ax)=80) and (y<24) then y:=y+1;
        if (lo(r.ax)=0) and (hi(r.ax)=75) and (x>1) then x:=x-1;
        if (lo(r.ax)=0) and (hi(r.ax)=77) and (x<80) then x:=x+1;
        if (lo(r.ax)<>0) and (lo(r.ax)<>8) and (lo(r.ax)<>13) and
        (lo(r.ax)<>27) then begin
            ch:=chr(lo(r.ax));
            write(ch);
        end;
        gotoxy(x,y);
    until (lo(r.ax)=27) and (hi(r.ax)=1);
end.

Если вы ее наберете на своем компьютере, странслируете и запустите на выполнение, то вы сразу заметите один ее недостаток - после нажатия символа курсор остается на том же самом месте и следующий нажатый символ сотрет предыдущий. Сделаем так, чтобы при нажатии очередного символа курсора перемещался на одну позицию вправо. Для этого после оператора write(ch) добавим еще один оператор x:=x+1. Далее. Если курсор находится в самой последней позиции строки ( в 80-ой), то он должен перемещаться не вправо (дальше некуда), а на 1-ю позицию следующей строки. Добавляем еще один оператор:

if x=81 then begin x:=1; y:=y+1 end

Теперь, если мы были на последней (24-ой строке), то мы должны переместиться не на одну строку вниз а в 1-ю строку. Добавляем еще один if.

if y=25 then y:=1

В итоге мы получаем следующую программу.

program AA;
uses crt, dos;
var
    r : registers;
    x, y : integer;
    ch : char;
begin
    clrscr; x:=1; y:=1;
    repeat
        r.ax:=$0000; Intr($16,r);
        if (lo(r.ax)=0) and (hi(r.ax)=72) and (y>1) then y:=y-1;
        if (lo(r.ax)=0) and (hi(r.ax)=80) and (y<24) then y:=y+1;
        if (lo(r.ax)=0) and (hi(r.ax)=75) and (x>1) then x:=x-1;
        if (lo(r.ax)=0) and (hi(r.ax)=77) and (x<80) then x:=x+1;
        if (lo(r.ax)<>0) and (lo(r.ax)<>8) and (lo(r.ax)<>13) and
        (lo(r.ax)<>27) then begin
            ch:=chr(lo(r.ax));
            write(ch);
            x:=x+1;
            if x=81 then begin x:=1; y:=y+1 end;
            if y=25 then y:=1
        end;
        gotoxy(x,y);
    until (lo(r.ax)=27) and (hi(r.ax)=1);
end.

Данная программа просто позволяет нам набирать текст на экране дисплея. Чтобы она стала текстовым редактором, нам необходимо добавить функции загрузки и сохранения этого текста в текстовый файл.

Добавим в программу массив символов Mass, который будет хранить все символы, появляющиеся на экране дисплея. Поскольку экран дисплея состоит из 24 строк и каждая строка содержит 80 символов, то этот двухмерный массив будет содержать 24 одномерных массива, каждый из которых, в свою очередь, содержит 80 элементов типа Char. Данный массив будет описан следующим образом:

Mass : array[1..24] of array[1..80] of char.

Первоначально, когда мы запускаем наш редактор, экран дисплея является пустым и массив Mass должен содержать только пробелы. Как только мы набираем на экране дисплея какой-то символ, то этот символ мы должны также поместить в соответствующий элемент массива Mass. Поскольку первое измерение массива Mass соответстует строкам экрана дисплея, а второе соответствуют позициям внутри строк, то переменных x и y будут одновременно использоваться и для задания координат на экране дисплея, и в качестве индексов в массиве Mass. По окончанию работы текстового редактора, мы должны содержимое массива Mass сохранить в текстовый файл. В результате получится следующая программа.

program AA;
uses crt, dos;
var
    r : registers;
    x, y, i, j : integer;
    ch : char;
    f : file of char;
    Mass : array[1..24] of array [1..80] of char;
begin
    for i:=1 to 24 do
        for j:=1 to 80 do Mass[i][j]:=' ';

    clrscr;    x:=1;    y:=1;
    repeat
        r.ax:=$0000; Intr($16,r);
        if (lo(r.ax)=0) and (hi(r.ax)=72) and (y>1) then y:=y-1;
        if (lo(r.ax)=0) and (hi(r.ax)=80) and (y<24) then y:=y+1;
        if (lo(r.ax)=0) and (hi(r.ax)=75) and (x>1) then x:=x-1;
        if (lo(r.ax)=0) and (hi(r.ax)=77) and (x<80) then x:=x+1;
        if (lo(r.ax)<>0) and (lo(r.ax)<>8) and (lo(r.ax)<>13) and
        (lo(r.ax)<>27) then begin
            ch:=chr(lo(r.ax));
            write(ch);
            Mass[y][x]:=ch;
            x:=x+1;
            if x=81 then begin x:=1; y:=y+1 end;
            if y=25 then y:=1
        end;
        gotoxy(x,y);
    until (lo(r.ax)=27) and (hi(r.ax)=1);

    assign(f,'aaa.txt'); rewrite(f);
    for i:=1 to 24 do
        for j:=1 to 80 do write(f,Mass[i][j]);
    close(f);
end.

Данная программа не загружает содержимое текстового файла, а только сохраняет его. Здесь мы использовали 1-ый тип текстового файла.

Переделаем данную программу для 3-го типа. Файл будет описан как f : text. А в качестве массива Mass будет использован:

Mass : array[1..24] of string[80].

program AA;
uses crt, dos;
var
    r : registers;
    x, y, i, j : integer;
    ch : char;
    f : text;
    Mass : array[1..24] of string[80];
begin
    for i:=1 to 24 do Mass[i]:='';

    clrscr;    x:=1;    y:=1;
    repeat
        r.ax:=$0000;    Intr($16,r);
        if (lo(r.ax)=0) and (hi(r.ax)=72) and (y>1) then y:=y-1;
        if (lo(r.ax)=0) and (hi(r.ax)=80) and (y<24) then y:=y+1;
        if (lo(r.ax)=0) and (hi(r.ax)=75) and (x>1) then x:=x-1;
        if (lo(r.ax)=0) and (hi(r.ax)=77) and (x<80) then x:=x+1;
        if (lo(r.ax)<>0) and (lo(r.ax)<>8) and (lo(r.ax)<>13) and
        (lo(r.ax)<>27) then begin
            ch:=chr(lo(r.ax));
            write(ch);
            (* ------- *)
            j:=length(Mass[y]);
            for i:=j to x-1 do
                Mass[y]:=Mass[y]+' ';
            (* ------- *)
            Mass[y][x]:=ch;
            x:=x+1;
            if x=81 then begin x:=1; y:=y+1 end;
            if y=25 then y:=1
        end;
        gotoxy(x,y);
    until (lo(r.ax)=27) and (hi(r.ax)=1);

    assign(f,'aaa.txt'); rewrite(f);
    for i:=1 to 24 do writeln(f,Mass[i]);
    close(f);
end.

Объясним назначение следующих операторов.

j:=length(Mass[y]);
for i:=j to x-1 do
Mass[y]:=Mass[y]+' ';

Теперь каждая строка массива Mass хранит не 80 символо, а ровно столько, сколько нужно. Может случиться так, что в данный момент строка содержит всего 3 символа, а мы хотим изменить 10-ый символ. Для этого нам сначала нужно удлинить строку до 10-ти символов. Вот это эти операторы и делают.

Если после запуска данного редактора вы войдете в другой редактор и загрузите в него текстовый файл aaa.txt, то вы увидите то, что вы набрали в нашем текстовом редакторе.

 

©   Александр Приходько    1996 - 2006

69 0