Опубликован: 04.05.2005 | Уровень: для всех | Доступ: платный | ВУЗ: Сибирский университет потребительской кооперации
Лекция 12:

Файлы

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >

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

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

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

DOMAINS
file=f
PREDICATES
Readfile
CLAUSES
readfile:–
        writedevice(screen), /* назначаем текущим 
                                устройством записи 
                                экран */
        write("Введите символ (# — конец ввода)"), nl,
                             /* выводим сообщение */
        readchar(C), /* читаем символ с клавиатуры */
        write(C), /* дублируем символ на экран */
        C<>'#',!, /* если это не #*/
        writedevice(f), /* , то перенаправляем вывод 
                           в файл */
        write(C), /* записываем символ в файл */
        readfile.
readfile:–
        closefile(f). /* если введенный символ оказался
               равен символу '#', то закрываем файл */
GOAL
write("Введите имя файла: "),
readln(F_N), 
    /* читаем название файла в переменную F_N */
openwrite(f,F_N), /* связываем внешний файл F_N 
                     с внутренним 	файлом f и открываем
                     его на запись */
readfile(f).

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

Пример. Запишем предикат, который будет выводить содержимое файла на экран и принтер. Предикат будет иметь один параметр, представляющий собой внутреннее имя файла.

Напишем только этот предикат, оставив "за кадром" проверку на существование внешнего файла, его открытие на чтение. Все это мы делали не раз. Наш предикат должен проверять, не достигнут ли конец файла. В случае достижения конца файла его нужно закрыть. Если мы еще не добрались до конца файла, читаем символ, используя предикат readchar. Выводим его на экран посредством предиката write, перенаправляем вывод на принтер предикатом writedevice, выводим символ на принтер, заставляем принтер немедленно напечатать символ, используя предикат flush, устанавливаем для последующего вывода символа текущим устройством записи информации экран. Повторяем этот процесс, пока не будут исчерпаны все символы исходного файла.

writeFile_to_scr_and_pr(f):–
                  not(eof(f)),!, /* если файл f еще 
                                    не закончился */
                  readchar(C), /* читаем из файла f 
                                  символ в переменную C */
                  write(C), /* выводим символ C на экран */
                  writedevice(printer), 
                               /* устанавливаем текущим 
                                  устройством записи 
                                  принтер*/
                  write(C), /* выводим символ C на экран */
                  flush(printer), 
                               /* сбрасываем данные из буфера 
                                  на принтер */
                  writedevice(screen), 
                               /* перенаправляем вывод 
                                  на экран*/
                  writeFile_to_scr_and_pr(f). 
                               /* продолжаем */
writeFile_to_scr_and_pr:–
                  closefile(f). /* закрываем файл f */

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

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

Пример. Напишем предикат, который будет переписывать компоненты одного файла в другой файл так, чтобы в итоговом файле все английские буквы были большими. У предиката будет два аргумента строкового типа. Первым параметром будет внешнее имя исходного файла, вторым параметром — внешнее имя итогового файла.

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

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

Запишем эти два предиката. Надеюсь, что недостающие разделы описаний читатели уже в состоянии дописать самостоятельно.

transform:–
          not(eof(f)),!, /* если файл f еще 
                            не закончился */
          readln(S), /* читаем из файла f строку 
                        в переменную S */
          upper_lower(S_U,S), 
                         /* S_U — результат преобразования 
                            всех символов строки S в верхний 
                            егистр */
          write(S_U),nl, /* записываем строку S_U 
                            в файл f_o */
          transform. /* продолжаем процесс */
transform:–
          closefile(f), /* закрываем файл f */
          closefile(f_o). /* закрываем файл f_o */
upper_file(N_F,N_o_F):–
          existfile(N_F),!, /* проверяем существование
                               файла с именем N_F */
          openread(f,N_F), /* связываем внешний файл 
                              с именем N_F с внутренним 
                              файлом f и открываем его 
                              на чтение */
          readdevice(f), /* устанавливаем в качестве 
                            текущего устройства чтения 
                            файл f */
          openwrite(f_o,N_o_F), 
                         /* связываем внешний файл с именем 
                            N_o_F с внутренним файлом f 
                            и открываем его на запись */
          writedevice(f_o), /* устанавливаем в качестве 
                               текущего устройства записи
                               файл f_o */
          transform. /* вызываем вспомогательный 
                        предикат */
upper_file(N_F,_):–
          write("Файл с именем ",N_F," не наден!"). 
                         /* выдаем сообщение, если предикат 
                            existfile был неуспешен */
< Лекция 11 || Лекция 12: 1234 || Лекция 13 >
Виктор Бондарь
Виктор Бондарь

После приведения формулы вида ПНФ к виду ССФ вы получаете формулу, в безквантовой матрице которой дизъюнкт содержит оба контранрных атома:. Как тогда проводить его унификацию, если в случае замены x на f(x) весь дизъюнкт обратится в единицу?

Ольга Потапенко
Ольга Потапенко

никак не могу увидеть тексты самих лекций.

Віталій Боярський
Віталій Боярський
Украина, Львов, НУЛП
олег носков
олег носков
Россия, г. Кисловодск