Средства ввода и вывода. Работа с файлами.
Средства ввода и вывода данных принадлежат к внелогическим предикатам Пролога, так как они формально не являются предикатами. К ним принадлежат: предикаты readreal(X), readint(X) и readln(X), предназначенные соответственно для чтения целого, действительного числа и строк. Предикат readchar(X) читает символ. Как известно, прочитанный символ может быть:
символом, который имеет отображение на экране;
управляющим символом (который не имеет отображения на экране и выполняет какое-то действие).
Символ, прочитанный предикатом readchar, относится к таким, которые не имеют отображения на экране независимо от символа, который вводится, и может использоваться для введения паролей.
Для ввода термов (констант, переменных, структур) используется предикат
readterm(тип терма, терм),
что позволяет вводить любые структуры.
Для вывода данных существует один предикат печати write(X), где X – переменная. Существует также возможность форматного вывода с помощью предиката
writef(формат-строка, последовательность объектов вывода).
Предикат выводит на логическое устройство константы и значения переменных в формате, заданном формат-строкой.
nl – переход в строке вывода на новую строчку.
Рассмотрим пример введение структуры с помощью предиката readterm с ее дальнейшим выводом в форматной форме
domains
address = street(string,integer)
predicates read_write
clauses read_write:-rеadterm(address, street(X,Y)),
writef(“улица ‘%s‘ дом N ‘%u’”, X, Y).
goal read_write.
Для значений X=“Шевченко”, Y=3 на экране будет отображена строка
улица Шевченко дом N 3.
Управляющий символ % показывает, что вывод следующего объекта из последовательности будет осуществляться в обозначенном формате
%s – строка;
%c – символ;
%u – целое без знака;
%d – обычное десятичное число.
Символ “-” указывает на выравнивание строки по левому краю.
Файлы
Программа на Прологе может взаимодействовать с несколькими файлами или устройствами. Но одновременно могут быть активными только два файла или устройства – один входной и один выходной.
При использовании в программе файлов ее необходимо снабдить описанием файлового домена, которое выглядит так:
file=datafile,
где file – стандартный тип домена (файловый),
datafile – логическое имя файла.
В файловом описании можно указывать несколько логических имен, но само описание должно быть единственным, например,
file=datafile1; datafile2; datafile3
Открытие файла выполняется стандартными предикатами:
openread(name_log, name_fis) – для последовательного чтения файла;
openwrite(name_log, name_fis) – для последовательной записи в новый файл; или замены содержимого существующего файла;
openappend(name_log, name_fis) – для работы с файлами прямым методом доступа (чтение и запись).
Здесь name_log, и name_fis соответственно символическое имя логического файла в программе и имя физического файла на диске.
Имя файла на диске задается в виде строки, в которой не допускается задавать устройство и путь к каталогу. Замена текущего диска и каталога выполняется с помощью стандартного предиката disk. После открытия файла все предикаты Пролога, синтаксис которых требует имени файла, работают с символическим именем. Символическое имя объявляется в разделе domains и в программе можно объявлять несколько символических имен для логических файлов.
Чтобы процедура могла работать с любым логическим файлом, в качестве символического имени можно использовать свободную переменную.
Кроме перечисленных выше предикатов при работе с файлами могут использоваться следующие встроенные предикаты Турбо-Пролога:
deletefile – удаления файла,
save – сохранения файла,
renamefile – переименования файла,
existfile – проверки наличия файла,
flush – сброса данных из внутреннего файлового буфера в заданный файл,
disk – установки накопителя и пути,
dir – вывода текущего каталога,
openmodify – открытия файлов для чтения/записи,
closefile – закрытия файла,
eof – проверки на конец файла,
filemode – установки или чтения типа файла,
filepos – установки или чтения позиции указателя в файле,
file_str – чтения строки из файла.
Логические устройства ТП. Для указания логическому устройству чтения, откуда вводить данные, используют стандартный предикат
readdevice(name_f),
а для указания логическому устройству записи, куда выводить данные – предикат
writedevice(name_f).
Предикаты применяют после открытия файла. Эти же предикаты используют для переназначения логического устройства на другой файл или устройство. ТП использует такие стандартные имена логических устройств
printer – принтер;
screen – экран;
keyboard – клавиатура.
После открытия файла, назначение логического устройства чтения файла или записи в файл выполняется стандартными предикатами ввода-вывода.
Например, при записи данных в файл последовательность действий следующая:
– открытие файла с помощью предиката openwrite;
– назначение файла в качестве устройства записи предикатом writedevice;
– сама запись в файл, например, с помощью предикатов write или writef;
– использование любых других предикатов и правил, отвечающих назначению программы;
– закрытие файла предикатом closefile.
Все эти действия в программе могут быть описаны следующим образом:
openwrite(datafile1,”File1.dat”),
writedevice(datafile1),
<запись в файл>
<любые другие правила или предикаты>
closefile(datafile1).
По такой же схеме могут быть описаны действия чтения данных из файла и дозаписи данных в файл.
Дополнение
Программа, осуществляющая считывание данных с клавиатуры и запись их в файл, может выглядеть так:
domains
file=datafile
kstr,fstr=string
predicates
readin(kstr,fstr) /* чтение-запись */
create_a_file /* создание файла */
goal
create_a_file.
clauses
create_a_file:-
nl,nl,write(“Введите имя файла”),nl,nl,
readln(Filename),
openwrite(datafile,Filename),
writedevice(datafile),
readln(Kstr),/* ввод первой строки с клавиатуры */
concat(Kstr,”\13\10”,Fstr),
readin(Kstr,Fstr),
closefile(datafile).
/* Ввод последующих строк и запись их в файл */
readin(“stop”,_):-!.
readin(_,Fstr):- write(Fstr),readln(Kstr1),
concat(Kstr1,”\13\10”,Fstr1),
readin(Kstr1,Fstr1).
В приведенной программе
Kstr – строка, вводимая с клавиатуры,
Fstr – строка, выводимая в файл.
Содержимым файла Filename будут дополненные символами “\13\10” вводимые пользователем строки. Дополнение строки символами “\13\10” необходимо для того, чтобы предикат readln мог различать строки при считывании их из файла в дальнейшем. Работа программы заканчивается, если введена строка “stop”.