Краткие теоретические сведения. 2.1 Файловая система Турбо-Пролога и переадресация каналов ввода и вывода

2.1 Файловая система Турбо-Пролога и переадресация каналов ввода и вывода

Составными частями компьютера являются устройства ввода/вывода, используемые программой на Турбо-Прологе во время ее работы. Например, для программы работающей в интерактивном режиме, с клавиатуры в компьютер вводятся целевые утверждения. Программа выводит на экран монитора результаты. Однако консоль является не единственным физическим устройством, которое может участвовать в работе программы. Большинство современных языков программирования высокого уровня обеспечивают интерфейс с операционной системой, который позволяет работать с различными физическими устройствами. Турбо-Пролог обеспечивает эту возможность путем поддержания предикатов, осуществляющих назначение каналам ввода и вывода различных устройств ввода\вывода или файлов, что позволяет вводить и выводить информацию с соответствующих устройств или файлов. Встроенный предикат Турбо-Пролога ReadDevice (<имя устройства или логического файла>) позволяет переадресовывать канал ввода на указанное устройство ввода или файл. Аналогично встроенный предикат WriteDevice (<имя устройства или логического файла>) осуществляет переадресацию каналов вывода информации на указанное устройство вывода или файл.

Пример.

Предикаты

readdeviсе(com1).

readdeviсе(dat.dat).

настраивают канал ввода на коммуникационный порт corn1 и логический файл dat.dat соответственно, а предикаты

writedevice(screen).

writedevice(printer)

настраивают канал вывода на экран и принтер.

В Турбо-Прологе по умолчанию каналу ввода назначается устройство ввода - клавиатура, а каналу вывода - экран монитора. Если эти назначения не устраивают,то необходимо воспользоваться предикатами переадресации каналов ввода и вывода. Чтобы иметь доступ к файлу, его надо открыть. Файл может быть открыт четырьмя способами:

- для чтения используется предикат

openread (<имя физического файла>, <имя логического файла>);

- для записи используется и предикат

openwrite (<имя физического файла>, <имя логического файла>);

- для добавления используется предикат

openappend (<имя физического файла>, <имя логического файла>);

- для модификации используется предикат

openmodify(<имя физического файла>, <имя логического файла>)

Файл, открытый для любых действий, кроме чтения, должен быть закрыт, когда действия закончены, в противном случае внесенные изменения могут быть утеряны. Для закрытия файла используется встроенный предикат closefile(<имя логического файла>).

Одновременно можно открыть несколько файлов, и канал ввода/вывода можно быстро переадресовать между открытыми файлами. Больше времени требуется на то, чтобы открыть и закрыть файл, чем на переадресацию канала ввода/вывода между ними.

После того, как файл открыт, Турбо-Пролог связывает имя логического файла с именем физического файла. Имя физического' файла - это имя файла в операционной системе (OC). Логическое имя файла Турбо-Пролог использует при переадресации канала ввода/вывода, Имя логического файла есть идентификатор и должно начинаться с маленькой буквы и объявлено в разделе domains после ключевого слова file. Объявление одного имени логического файла выглядит как domains

file<имя логического файла>,

а нескольких

domains

file<имя логического файла 1>;<имя логического файла 2>...

В программе может быть только одно поле объявления файлов - file.

Турбо-Пролог автоматически заранее объявляет четыре имени:

- printer (относится к параллельно-печатающему порту);

- screen (относится к экрану монитора); .

- keyboard (относится к клавиатуре);

- com1 (относится к последовательному порту связи).

Эти имена не должны появляться при объявлении файлов.

2.2 Организация обработки файлов

В наиболее общем виде запись информации в файл может быть представлена следующей последовательностью действий:

openwrite(datafile, ''Dat.dat''),

writedevice(datafile)

<предикаты записи в файл>

<любые предикаты>

closefile(datafile).

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

opendevice(datafile, ''Dat.dat''),

readdeviсе(datafile)

<предикаты чтения в файл>

<любые предикаты>

closefile(datafile).

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

Модификация файла:

openmodify (datafile,'Dat.dat''),

readdeviсе(datafile),

writedevice(datafile),

<предикаты для выборочного чтения и записи в файл>

<любые предикаты>

closefile(datafile).

Добавление в файл:

openappend (datafile,'Dat.dat''),

writedevice(datafile),

<предикаты для дозаписи в файл>

<любые предикаты>

closefile(datafile).

2.3 Предикаты Турбо-Пролога для работы с файлами

Для работы с файлами в системе Турбо-Пролог имеются следующие предикаты.

openread(<имя физического файла>, <имя логического файла>);

Здесь физический файл открывается для чтения. Если файл не найден, то предикат не выполняется (не успешен). Если имя физического файла является недопустимым, то сообщается об ошибке.

openwrite(<имя физического файла>, <имя логического файла>);

Физический файл открыт для записи. Если файл существует, то он очищается. Если нет он создается и заносится в текущий каталог ОС.

openappend(<имя физического файла>, <имя логического файла>)

Физический файл открыт для добавления информации в конец файла. Если файл не найден, то выводится сообщение об ошибке.

openmodify(<имя физического файла>, <имя логического файла>)

Физический файл открыт для чтения и записи. Предикат openmodify может использоваться со стандартным предикатом filepos для обновления файлов прямого доступа.

closefile(<имя логического файла>).

Предикат закрывает файл, т.е. разрывает связь логического файла с физическим, Даже если файл не был открыт, ошибки не будет,

readdeviсе (<имя устройства или логического файла>).

Переадресовывает канал - ввода на указанное устройство или файл, открывая их для чтения. Если имя логического файла было свободно, то оно связывается с текущим назначением канала ввода.

writedevice (<имя устройства или логического файла>).

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

exitsfile(<имя физического файла>).

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

eof(<имя логического файла>).

Предикат успешен, если достигнут конец файла, и не успешен в противном случае.

В Турбо-Прологе имеется ряд других стандартных предикатов для работы с файлами. Описание этих предикатов приводится в соответствующей литературе по Турбо-Прологу.

2.4 Примеры организации файловой обработки

2.4.1 Вывод информации, вводимой с клавиатуры на экран дисплеи и файл на диске

domains

file=dateFile

predicates

check(string)

wr_linеs.

clauses

wr_lines:- readln(X),

write(Х), nl,

writedevice(datafile),

write(X), nl,

writedevice(screen),

check(X).

wr_linеs.

check("end"):-!.

check(_):-fail.

goal

openwrite(datafile,''Dat.dat''),

wr lines,

closefile(datafile).

Обрабатываемая информация вводится с клавиатуры построчно: Последняя строка - end.

2.4.2 Чтение данных из файла и вывод их на экран

domains

file=datafile

predicates

read_write.

goal

openread(datafile,'Dat.dat'')),

readdeviсе(datafile),

read_write,

closefile(datafile).

clauses

read_write:-not(eof(datafile)),

readln(Line),

write(Line),nl,

read_write.

read_write.

2.5 Файлы прямого доступа

Файл прямого доступа - это файл, позволяющий работать с произвольной записью в нем без предварительного чтения предыдущих записей. Файлы, где нельзя без этого обойтись. называются файлами последовательного доступа. Файлы, рассматриваемые до сих пор, были именно таковыми.

В файлах прямого доступа все записи имеют одинаковую длину. Указатель перемещается по позициям кратным длине записи, он указывает всегда на начало очередной записи. Турбо-Пролог содержит встроенный предикат, который удобен для работы с файлами прямого доступа: filepos.

filepos (<имя логического файла>, <позиция в файле>, <режим>).

<позиция в файле> указывает позицию, из которой будет считан или в которую будет записан символ.

<режим> может иметь одно из трех значений 0, 1, 2. Эти значения определяют, как будет ориентировано значение аргумента.

<позиция в файле> определяется по таблице 3.

Таблица 3

Режим Действие системы
Смещение берется относительно начала файла
Смещение берется относительно текущей позиции
Смещение берется относительно конца файла

Например:

- filepos(f,100,0)

указатель передвигается к 100-й позиции от начала файла;

- filepos (f,100,1)

указатель смещается на 100 позиций вправо относительно текущей позиции файла;

- filepos(f,-100,1)

указатель смещается на 100 позиций влево относительно текущей позиции файла;

- filepos(f,-100,2) указатель сдвигается на 100 позиций влево относительно конца файла.

Предикат filepos может изменить позицию чтения и записи файла, который был открыт по openmodify. Предикат filepos может возвращать текущую файловую позицию, если переменная <позиция в файле> не связана и <режим> = 0.

Примечание - Начальная позиция файла - нулевая

2.6 Пример обработки файла прямого доступа

Работа с файлами прямого доступа требует знания структуры этого файла. Нужно знать, к примеру, длину каждой записи файла, число записей, начальную позицию первой записи.

Приведем программу чтения n-ой записи из файла прямого доступа. Номер интересуемой записи вводится по запросу с клавиатуры. Предполагается, что длина каждой записи 40 позиций, начальная позиция первой записи нулевая и число записей равно 100.

domains

file=f

predicates

read_file

clauses

read_file:-

write(''Введите ими файла:"),nl,

readln(F),

openmodify(f, F)

write("Введите номер записи: "),nl,

readint(N),

N>0, N<=100, !,

l=(N-1)*40

readdeviсе(f)

filepos(f, l, 0)

readln(C)

write(C), nl, nl,

write(''Нажмите пробел''), nl,

readdeviсе(keyboard),

readchar(_),

closefile(f),

read_file:-write(''*Ошибка ввода*'').

goal

read_file

В случае указания несуществующего имени физического файла или указания несуществующего номера записи в файле печатается сообщение об ошибке ввода.

2.7 Предикаты для работы с окнами

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

2.7.1 Предикат для создания окон

makewindow(Window_number,

Screen_attribute, t

Frame_attribute

Frame_string

Starting_row

Starting_column

Window_height,

Window_width).

Параметр Window_number, целое число, идентифицирует окно в программе. Это число используется в качестве ссылки предикатом shift_window и др. В длиной программе организуется 5 различных окон, т.е. значение параметра Window_number будет изменяться от 1 до 5.

Целочисленные значения Screen_attribute задают комбинацию цветов текста и фона в окне, Для создаваемых окон выбраны белые символы на черном фоне, т.е. значение параметра Screen_attribute=7.

Для цветного экрана параметр формируется по формуле screen_attribute = S+А, где S - цвет текста, а А - цвет фона (таблица 4)

Таблица 4

Цвет текста (символа) S Цвет фона A
Черный Черный
Синий Синий
Зеленый Зеленый
Голубой Голубой
Красный Красный
Фиолетовый Фиолетовый
Краткие теоретические сведения. 2.1 Файловая система Турбо-Пролога и переадресация каналов ввода и вывода - student2.ru Коричневый Коричневый
Белый Белый
Серый    
Светло-синий    
Светло-зеленый    
Светло-голубой    
Светло-красный    
Светло-фиолетовый    
Желтый    
Интенсивно-белый    

Для вывода символов с мерцанием параметр формируется по формуле screen_attribute = S+А+128.

Аргумент Frame_attribute есть целое число, значение которого задает цвет рамки (таблица 5). Для белой рамки Frame_attribute = 7.

Аргумент Starting_row - целое число. Определяющее верхнюю строку(лишнюю) создаваемого окна.

Аргумент Starting_column - целое число, указывающее крайний левый столбец Окна.

Аргумент Window_height - целое число, определяющее количество строк, занимаемых создаваемым окном.

Аргумент Window_width - целое число, указывающее число столбцов, занимаемых окном.

2.7.2 Предикат смены текущего окна

shift_window(Window_number).

Параметр Window_number является целым числом, приписываемым окну при его создании. (Это параметр Window_number предиката makewindow).

Значение предиката shift_window(3) вызывает переназначение всех операций ввода и вывода в окно с номером 3.

Таблица 5

Значение аргумента Frame_attribute Вид рамки  
Нет рамки  
Зеленая рамка  
Синяя рамка  
Светло-синяя рамка  
Красная рамка  
Краткие теоретические сведения. 2.1 Файловая система Турбо-Пролога и переадресация каналов ввода и вывода - student2.ru 5 Фиолетовая рамка  
Желтая рамка  
Белая рамка  
Коричневая рамка  
-1 Мерцающая белая рамка  
-2 Мерцающая желтая рамка  
-3 Мерцающая фиолетовая рамка  
-4 Мерцающая красная рамка  
-5 Мерцающая светло-синяя рамка  
-6 Мерцающая светло-зеленая рамка  
Краткие теоретические сведения. 2.1 Файловая система Турбо-Пролога и переадресация каналов ввода и вывода - student2.ru -7 Мерцающая синяя рамка  
-8 Мерцающая серая рамка

2.7.3 Предикат удаления текущего окна с экрана

Removewindows

Все текстовые и графические изображения, находящиеся в окне так же удаляются. Если за данным окном находится другое окно, то это окно и его содержимое становятся видимыми.

2.7.4 Предикат очистки текущего окна

Clearwindow

2.8 Пример организации многооконного меню в программе обработки файла прямого доступа

Модуль menu высвечивает в главном окне программы доступные пользователю функции обработки файла:

- создание файла прямого доступа;

- добавление элемента в файл;

- модификация файла

- просмотр файла;

- окончание работы программы.

Модуль запрашивает у пользователя режим работы N в соответствии с выбранной функцией обработки файла или окончанием работы. С помощью repeat и N=5 осуществляется выбор новых необходимых видов обработки файла. В соответствии с выбранным режимом работы N осуществляется выбор правил:

- process(1) - для создания файла прямого доступа;

- process(2) - для добавления информации в файл;

- process(3) - для модификации информации в файле;

- process(4) - для просмотра информации, находящейся в файле;

- process(5) - для окончания работы программы.

Первые четыре из этих модулей создают свои диалоговые окна.

В программе предусмотрены реакции программы на ошибки при вводе выбираемого режима работы и при не указании имени физического файла.

domains

file=f

predicates

menu

repeat

namefile(string)

input(string)

read

process(integer)

print

error

clauses

menu:-repeat, makewindow(1, 7, 7, ''ГЛАВНОЕ МЕНЮ'', 0, 0, 25, 70),

write(''****************************************''), nl,

write(''*****ФУНКЦИИ ОБРАБОТКИ ФАЙЛА*****''), nl,

write(''****************************************''), nl,

write("***1. Создание файла ***"), nl,

write("***2. Добавление элемента в файл ***"), nl,

write("***3. Модификация файла ***"), nl,

write("***4. Просмотр файла ***"), nl,

write("***5. Окончание работы ***"), nl,

write(''****************************************"), nl, nl, nl,

write(''ВАШ ВЫБОР (1 ..5): "), readint(N),

process(N), N=5,!.

repeat.

repeat:-repeat.

process(1):-makewindow(2,7,7,"СОЗДАНИЕ ФАЙЛА'',0,10,25,30), nl,nl

write("Введите имя файла ''),readln(F},

namefile(F),

openwrite(f, F),

closefile(f)

openappend(f, F),

write("Будете вводить (y/n): "),

readln(C),

input(C),

closefile(f),

removewindows.

process(2):-makewindow(3,7,7,"ДОБАВЛЕНИЕ ЭЛЕМЕНТА",0,10,25,30), nl, nl,

write("Введите имя файла "),

readln(F),

namefile(F),

openappend(f,F},

input(''y''),

closefile(f),

removewindows.

process(3):-makewindow(4,7,7," ДОБАВЛЕНИЕ ЭЛЕМЕНТА",10,10,10,30), nl, nl,

write("Введите имя файла ''),

readln(F),

namefile(F),

openmodify(f, F),

write("Номер записи: "),

readint(N), l:=(N-1)*7,

readdeviсе(f),

filepos(f, l, 0),

readln(С),

write(C), nl, nl,

readdeviсе(keyboard),

write("Вверните новое значение:"), nl,

readint(K),

filepos(f,1,0),

writedevice(f)

write("%5.0", K),

writedevice(screen),

closefile(t),

removewindows.

process(4):-makewindow(5 7 7 ''ПРОСМОТР ФАЙЛА",0,10,25,30), nl, nl,

write("Введите имя файла "),

readln(F),

namefile(F),

openread(f, F),

readdeviсе(f),

writedevice(screen),

print,

closefile(f),

removewindows.

process(5):-nl, write("КОНЕЦ" ), nl,

write("Нажать пробел"),

readchar(_).

error:-nl,

write("ОШИБКА ВВОДА"), n1,

write("Нажмите пробел" ),

readchar(_).

print: -not(eof(f), !,

readln(N),

write(N), n1,

print.

print:-readdeviсе(keyboard).

namefile(""):-!,

write("***ОШИБКА ВВОДА***"), nl,

write(''Нажмите пробел"),

readchar(),

fail

namefile(f).

input(''y''):-!,

write( ''Ведите элемент: "),

read,

write(''Будете еще вводить? (y/n):''),

readln(C),

input(C)

input(_)

read:-readint(K), !,

writedevice(f),

writef("%5.0", K),

writedevice(screen)

read.

Наши рекомендации