Выбрать главу

end;

end;

Приведем вид окна задачника для новых заданий:

Добавление заданий на обработку файлов

Добавим к группе MakerDemo еще два задания: первое из них дублирует задание File63 (подгруппа Символьные и строковые файлы"), а второе -- задание Text16 (подгруппа "Текстовые файлы: основные операции"). Реализуем эти задания в процедурах MakerDemo6 и MakerDemo7:

function FileName(Len: integer): string;

const

c = '0123456789abcdefghijklmnopqrstuvwxyz';

var

i: integer;

begin

result := '';

for i := 1 to Len do

result := result + c[RandomN(1, Length(c))];

end;

procedure MakerDemo6;

var

k, i, j, jmax: integer;

s1, s2, s3: string;

fs1: file of ShortString;

fs2: file of ShortString;

fc3: file of char;

s: ShortString;

c: char;

begin

CreateTask('Символьные и строковые файлы');

TaskText(

'Дано целое число~{K} (\,0) и строковый файл.'#13 +

'Создать два новых файла: строковый, содержащий первые {K}~символов'#13 +

'каждой строки исходного файла, и символьный, содержащий {K}-й символ'#13 +

'каждой строки (если длина строки меньше~{K}, то в строковый файл'#13 +

'записывается вся строка, а в символьный файл записывается пробел).'

);

s1 := '1' + FileName(5) + '.tst';

s2 := '2' + FileName(5) + '.tst';

s3 := '3' + FileName(5) + '.tst';

Assign(fs1, s1);

Rewrite(fs1);

Assign(fs2, s2);

Rewrite(fs2);

Assign(fc3, s3);

Rewrite(fc3);

k := RandomN(2, 11);

jmax := 0;

for i := 1 to RandomN(10, 20) do

begin

j := RandomN(2, 16);

if jmax < j then

jmax := j;

s := FileName(j);

write(fs1, s);

if j >= k then

c := s[k]

else

c := ' ';

write(fc3, c);

s := copy(s, 1, k);

write(fs2,s);

end;

Close(fs1);

Close(fs2);

Close(fc3);

DataN('K = ', k, 0, 1, 1);

DataS('Имя исходного файла: ', s1, 3, 2);

DataS('Имя результирующего строкового файла: ', s2, 3, 4);

DataS('Имя результирующего символьного файла: ', s3, 3, 5);

DataComment('Содержимое исходного файла:', xRight, 2);

DataFileS(s1, 3, jmax + 3);

ResultComment('Содержимое результирующего строкового файла:',

0, 2);

ResultComment('Содержимое результирующего символьного файла:',

0, 4);

ResultFileS(s2, 3, k + 3);

ResultFileC(s3, 5, 4);

end;

procedure MakerDemo7;

var

p: integer;

s, s1, s2, s0: string;

t1, t2: text;

begin

CreateTask('Текстовые файлы: основные операции');

TaskText('Дан текстовый файл.', 0, 2);

TaskText('Удалить из него все пустые строки.', 0, 4);

s1 := FileName(6) + '.tst';

s2 := '#' + FileName(6) + '.tst';

s := TextSample(RandomN(0, TextCount-1));

Assign(t2, s2);

Rewrite(t2);

Assign(t1, s1);

Rewrite(t1);

writeln(t2, s);

Close(t2);

s0 := #13#10#13#10;

p := Pos(s0, s);

while p <> 0 do

begin

Delete(s, p, 2);

p := Pos(s0, s);

end;

writeln(t1, s);

Close(t1);

ResultFileT(s1, 1, 5);

Rename(t2, s1);

DataFileT(s1, 2, 5);

DataS('Имя файла: ', s1, 0, 1);

SetTestCount(3);

end;

При реализации этих заданий используется вспомогательная функция FileName(Len), позволяющая создать случайное имя файла длины Len (без расширения). Имя файла при этом будет содержать только цифры и строчные (маленькие) латинские буквы.

Имена файлов, полученные с помощью функции FileName, дополняются расширением .tst (заметим, что в базовых группах File, Text и Param это расширение используется в именах всех исходных и результирующих файлов).

Функция FileName используется также для генерации элементов строкового файла в процедуре MakerDemo6.

Для того чтобы предотвратить возможность случайного совпадения имен файлов, в процедуре MakerDemo6 к созданным именам добавляются префиксы: 1 для первого файла, 2 для второго, 3 для третьего. В процедуре MakerDemo7 имя временного файла дополняется префиксом #, что также гарантирует его отличие от имени основного файла задания.

В процедуре MakerDemo6 использован новый вариант процедуры TaskText, появившийся в версии 4.11 задачника. В этом варианте процедура TaskText принимает один строковый параметр, который определяет всю формулировку задания, причем в качестве разделителей строк, входящих в формулировку, можно использовать символы #13, #10 или их комбинацию #13#10 (в указанном порядке). Новый вариант процедуры TaskText позволяет более наглядно отобразить формулировку задания и не требует указания дополнительных параметров.

При реализации задания на обработку текстовых файлов для генерации содержимого файла используются функции TextCount и TextSample. Строка, возвращаемая функцией TextSample, представляет собой текст, содержащий маркеры конца строки -- символы #13#10. Указанные символы разделяют соседние строки текста (в конце текста маркер конца строки не указывается). Благодаря наличию маркеров конца строки полученный текст можно записать в текстовый файл с помощью единственной процедуры writeln, которая, кроме записи текста, обеспечивает добавление маркера конца строки в конец файла.

После разработки новых заданий необходимо изменить количество заданий в вызове процедуры CreateGroup на 7 и включить вызовы новых процедур в основную процедуру группы InitTask:

procedure InitTask(num: integer);

begin

case num of

1..2: UseTask('Begin', num);

3: MakerDemo3;

4: MakerDemo4;

5: MakerDemo5;

6: MakerDemo6;

7: MakerDemo7;

end;

end;

Приведем вид окна задачника для новых заданий:

Добавление заданий на обработку динамических структур данных

Наконец, добавим в нашу группу задание, посвященное обработке динамических структур данных, причем представим его в двух вариантах: традиционном, основанном на использовании записей типа TNode и связанных с ними указателей типа PNode, и объектном", характерном для .NET-языков (C#, Visual Basic .NET, PascalABC.NET), а также языков Python и Java. Следует подчеркнуть, что при разработке как традиционного, так и объектного варианта заданий на динамические структуры надо использовать типы TNode и PNode и связанные с ними процедуры конструктора учебных заданий. В то же время, при выполнении объектного варианта задания на соответствующем языке требуется использовать объекты типа Node (которые при разработке задания не применяются).