Реферат: Из опыта создания универсальных тестовых редакторов
clrscr;
Window(30,5,50,10); {открытие окна характеристик}
TextBackGround(yellow);
clrscr;
GoToXY(30,6);
Write('кол-во вопросов ');
Readln(d); {ввод количества вопросов}
Writeln(c,' ',d);
GoToXY(30,8);
Writeln('название теста '); {ввод названия теста}
Readln(f);
Writeln(c,f);
Writeln('пароль на защиту');
Readln(f); {ввод пароля}
Writeln(u,f);
Window(30,5,50,10);
TextBackGround(black);
clrscr;
For i:=1 to d do Begin
Writeln(c);
Window(10,10,53,20); {окно вопроса}
TextBackGround(lightgray);
clrscr;
Writeln(i,'-й вопрос: ');
Readln(a); {ввод вопроса}
Str(i,f);
f:=f+')'; {запись вопроса в файл}
Writeln(c,f);
Writeln(c,a);
Window(55,10,80,15); {окно количества ответов}
TextBackGround(cyan);
clrscr;
Write('количество ответов на ',i,'-й вопрос ');
Readln(e); {ввод количества ответов}
Window(10,10,53,20); {окно ответов}
TextBackGround(lightgray);
clrscr;
For j:=1 to e do Begin
Write(' ',j,')');
Readln(a); {ввод ответов}
Str(j,f);
a:=' '+f+')'+a;
Write(c,a);
End;
Write(c,'&'); {запись в файл конца ввода}
Window(55,10,80,15);
TextBackGround(cyan); {окно правильного ответа}
clrscr;
Write('Правильный ответ: ');
Readln(b); {ввод правильного ответа}
Writeln(u,b);
End;
close(u); {закрытие файлов и окон}
Reset(u);
Readln(u);
close(c);
Window(55,10,80,15);
TextBackGround(black);
clrscr;
End;
В этой, как и в других функциях, работающих с файлами, я столкнулся с проблемой записи тестов в файлах. Во-первых, я решил разделить сам тест и ответы к нему. Тест находится в файле с расширением qs, а ответы к нему- в файле с расширением qso. Второй проблемой стала остановка чтения вопроса, ведь вопросы должны выводиться не подряд, а по очереди. В связи с этим я использовал символ «&» в конце каждого вопроса и указал программе читать до этого символа, но сам символ не выводить. Можно было использовать счетчик строк, который останавливает программу после прочтения двух строк (вопрос и варианты ответов), но в случае сбоя тест приходит в негодность. Далее требовалось разместить данные о названии теста, количестве вопросов, пароле и т. п. Я разместил их по этим двум файлам. Опытные программисты заметят: зачем было использовать текстовые файлы, ведь можно было применить работу с типом «запись» и сохранять данные в нетипизированных файлах, и шифровщик бы не потребовался. Действительно, но использование типа «запись» не позволяет создавать тесты с динамическим числом ответов на вопрос. Это возможно лишь путем использования в записи динамического массива. Но это сделает работу с файлом очень сложной а сам файл будет занимать много места на диске по сравнению с обычным текстовым.
Естественно, что при поиске файла программа может его не найти, в этом случае выдается ошибка поиска. Требовалось ее обойти, выдавая собственное сообщение программы. Это осуществляется следующим образом: задается директива компиллятора на его отключение $I-, проверяется нулевой результат IORESULT=0, выдается сообщение и компиллятор включается снова $I+. Я использовал эту функцию компиллятора там, где необходимо осуществить поиск файла. Такая функция обхода компилятора называется обработкой сообщений и является составляющей объектного програмимирования.
Функция открытия теста выглядит сложнее. Она открывает указанный файл, считывает сначала пароль входа и запрашивает его, затем приступает к выполнению теста. На экран выводится вопрос и ожидается ввод цифры правильного ответа. Причем включается таймер и по завершении работы с тестом или по истечении времени программа выходит из данной функции и передает управление подпрограмме подсчета результатов и регистрации:
Procedure OpenF;
label l1;
Var f1:string; {объявление локальных переменных}
Begin
p:=0;
Window(10,10,53,15);
TextBackGround(black);
TextColor(black);
clrscr;
Window(20,10,66,15); {начальное окно}
TextBackGround(blue);
clrscr;
Writeln('какой файл открыть ');
Readln(a); {ввод пути к файлу без расширения}
a:=a+'.ts'; {прибавление расширения}
Assign(c,a); {связь переменной с файлом вопросов}
f1:=a;
a:=a+'o'; {изменение расширения}
Assign(u,a); {связь переменниой с файлом ответов}
delete(a,length(a),1);
Assign(b1,'c:\pascal\registr.dat'); {связь переменной с файлом отчета}
Append(b1); {открытие файла отчета для дозаписи}
Reset(c); {открытие файла вопросов для чтения}
Window(20,10,66,15); {закрытие начального окна}
TextBackGround(black);
clrscr;
Reset(u);
Read(c,b); {считывание пароля}
Readln(c,b);
z:=ord(b)-ord('0'); {установка времени}
z1:=z;
Window(10,10,40,12); {окно пароля}
TextBackGround(magenta);
clrscr;
Readln(u,a);
If length(a)>2 Then Begin{проверка наличия в файле пароля}
Write('введите пароль ');
Readln(f); {ввод пароля}
If a<>f Then Begin
Write('пароль неверный');
GoTo l1; {выход из процедуры}
End;
End
else Begin
close(u);
Reset(u);
End;
Readln(c,f);
Writeln('тест по теме "',f,'"'); {вывод темы теста}
z2:=60;
repeat
Window(60,20,70,21); {закрытие окна пароля}
TextBackGround(black);
clrscr;
TextColor(yellow);
z2:=z2-1; {включение таймера}
If z2<0 Then Begin
z1:=z1-1;
z2:=60;
End;
If (z1=0)and(z2=0) Then GoTo l1;
Writeln(z1,':',z2);
GetTime(g1,g2,g3,g4); {вывод текущего времени}
Write(g1,':',g2,' ',g3);
Delay(1000);
TextColor(black);
Window(10,10,53,15); {вывод вопроса, ожидание ввода ответа}
TextBackGround(cyan);
clrscr;
while not Eoln(c)or(b<>'&') do Begin
Read(c,b);
If b<>'&' Then Write(b);
End;
Writeln;
Window(55,10,80,15); {вывод сообщения о вводе ответа}
TextBackGround(blue);
clrscr;
Write('ваш ответ ');
TextColor(yellow);
repeat{таймер}
Window(60,20,70,21);
TextBackGround(black);
clrscr;
z2:=z2-1;
If z2<0 Then Begin
z1:=z1-1;
z2:=60;
End;
If (z1=0)and(z2=0) Then GoTo l1;
GetTime(g1,g2,g3,g4);
Writeln(z1,':',z2);
Write(g1,':',g2,' ',g3);
Delay(1000);
until keypressed;
Window(55,10,80,15);
TextBackGround(blue);
clrscr;
TextColor(yellow);
b:=readkey; {считывание цифры ответа}
Write(b); {считывание правильного ответа из файла}
Readln(u,k);
Readln(c);
If k=b Then p:=p+1; {сравнение ответов, начисление баллов}
Window(60,20,70,21);
TextBackGround(black); {закрытие окна отверов}
clrscr;
TextColor(black);
z2:=z2-1; {таймер}
If z2<0 Then Begin