Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по языку Пролог.doc
Скачиваний:
83
Добавлен:
28.06.2014
Размер:
507.39 Кб
Скачать

4.4. Переопределение стандартного ввода-вывода

. Домен file имеет три дополнительные опции: stdin, stdout, stderr. Преимущество этих файлов в том, что вы можете указать операционной системе ДОС на необходимость переназначения стандар­тного ввода-вывода в командной строке.

stdin

Стандартный ввод является файлом, доступным толькодля чтения. По умолчанию это клавиатура readdevice (stdin) назначает устройством ввода stdin.

stdout.

Стандартный вывод является файлом, доступным,только для записи. По умолчанию это экран терминала.Writedevice (stdout) назначает устройством вывода stdout.

stderr

Стандартный вывод ошибок является файлом. Доступен

только для записи. Это всегда экран терминала

writedevice (stderr) назначает устройством для вывода

сообщений об ошибках экран.

4.5. Работа с файлами

В этом разделе будет описано несколько других предикатов для работы с файлами. Это предикаты filepos, eof, flush, existfile,de-letefile, renamefile и disk.

Предикат filepos может управлять позицией, где производится чтение или запись. Он имеет формат:

filepos (SynbolicFileName, FilePosition, Mode) /*(i;i,i),(i,o,i) */

Если FilePosition - связанная переменная, предикат может из­менить позицию чтения и записи для файла. Если при вызове FilePosition является свободной переменной, то SymbolicFileNan» возвращает текущую позицию в файле.

FilePosition должно иметь вещественное значение (любая дроб­ная часть игнорируется).

Mode является целой и указывает, как значение должно интерпретироваться (согласно таблице 4.1.) значение FilePosition.

Когда возвращается FilePositson, filepos возвращает позицию относительно начала файла.

Замечание: При использовании filepos, новая строка 8 файле считается как два символа.

Таблица 4.1

Mode

FilePosition

0

Относительно начала файла.

1

Относительно текущей позиции.

2

Относительно конца файла. (Конец файла соответствует позиции 0.)

Примеры. Следующая последовательность запишет значение Text в файл SOMEFILE. PRO (к которому Пролог обращается, _как к myfilе ), начиная с позиции 100 (относительно начала файла).

Text * "A text to be written in the file",

openmodiry(myfile,"somefile.pro")

writedevice (myfile),

filepos(myfile,100,0),

write(Text).

Используй filepos, можно проверить содержимое файла байт за байтом, как это сделано в следующей программе. Эта программа запра­шивает имя файла, затем показывает содержимое позиций файла, при­чем номера позиций вводятся клавиатуры.

domains

file = input

predicates

inspect_positions goal

write("Which file do you want to work with?"),

readln(FileName),

openread( input,FileName),

inspect_positions. clauses

inspect_position :-readdevice(keyboard),

nl,write("Position No? ") , readreal(X),

readdevice( input), filepos(input, X,0),

readchar(Y),write("Char is:",Y), inspect_positions.

Предикат eof проверяет является ли позиция, полученная в процессе чтения, концом файла. В этом случае eof успешна. В про­тивном случае он терпит неудачу. eof имеет вид:

eof (SymbolicFileName) /* (i) */

Предикат eof можно использовать для определения предиката repfile, который полезен при работе с файлами, repfile генерирует точку возврата до тех пор, пока не будет достигнут конец файла.

predicates

repfile(FILE) clauses

repfile(_).

repfile(F): -not(eof(F)(),repfile(F).

Следующая программа преобразует один файл в другой, все бук­вы которого являются прописными.

domains

file = input; output predicates

convertfille

repfile(FILE) goal

wite(Which file do you want convert ?"), readln(InputFileName),

wite(What is the name of the output file/"),

readln(OutputFileName),

openread (input,InputFileName), readdevice(input), openwrite (output,OutputFileName), writedevice(output), convertfile, closefile(input), closefile(output). clauses

convertfile: -

repfile(input),

readln(Ln),

upper_lower( LnInUpper,Ln),

/* перевод букв строки в заглавные*/_

write(LnInUpper),nl,

fail.

convertfile. repfile(_), repfile(F): -not(eof(F),repfile(F).

Предикат flush записывает содержимое внутреннего. буфера в названный файл. Имеет формат:

flush (SymbolicFileName) /*(i) */

Предикат flush полезен, когда вывод направляется на устрой­ство печати, и вам необходимо выдать данные на печать до того, как буфер заполнится.

Замечание: После операции flush, так как ДОС перед

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

обеспечивается сохранность дисковых файлов. Единственный

путь гарантировать целостность дискового файла: это закрыть

его (и снова открыть, когда это будет необходимо).

Предикат existfile выполняется успешно, если файл DosFileName будет найден в каталоге ДОС на текущем дисковом уст ройстве. Формат его следующий:

existfile(DosFileName) /*(i) */

Предикат existfile терпит неудачу, если имя не найдено в ка­талоге или имя файла неправильно, или содержит глобальные симво­лы поиска (например, MY*.PRO или ??PROJ.* ).

Для проверки того, что файл присутствует на диске, прежде чем открывать его вы можете использовать следующую последовательность:

open(File,Name): -

existfile(Name),£,

openread(File,Name). open(_,Name) : -

write("Error: the file ",Name," is not found").

Предикат deletefile удаляет файл, заданный его аргументом и имеет такой формат:

deletefile(DosFileName) /*(i) */

Предикат deletefile даст ошибку, если не сможет удалить файл.

Предикат renamefile переименовывает файл с именем OldDosFileName в NewDosFileName. Имеет формат:

renamefile(0ldDosFileName,NewDosFileName) /* (i,i) */

Предикат renamefile будет успешен, если файл с именем

NewDosFileName еще не существует, и оба имени являются допустимыми.

В противном случае будет выдана ошибка

Предикат disk используется для изменения текущего диска и каталога/подкаталога и имеет формат:

disk(DosPath) /*(i) (о) */

При вызове свободной переменной в качестве параметра disk возвратит текущий каталог.