Работа с файлами SWI Prolog

      Комментарии к записи Работа с файлами SWI Prolog отключены

Помечено: , ,

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 2 года/лет, 6 мес. назад.

  • Автор
    Сообщения
  • #1852

    questioner
    Участник

    Пытаюсь заставить пролог считывать строки с файла, ничего не получается.

    ?- see(‘D:/input.txt’),read(T),seen,write(T).
    ERROR: D:/input.txt:4:0: Syntax error: Unexpected end of file
    2 ?- see(‘D:/input.txt’),read(T),seen,write(T).
    end_of_file
    T = end_of_file.

    В файле написан обычный текст. Расскажите что делают функции see и seen, пожалуйста.

  • #1853

    У пролога есть ряд функций, обеспечивающих ввод и вывод:

    • read/1 осуществляет ввод терма с входного потока, на прологе они завершаются точкой. Термами являются, например, числа, строки (в одинарных кавычках) и списки (в том числе списки символов и кодов символов).
    • readln/1 считывает символы до конца строки, формируя список слов (в одинарных кавычках);
    • get_char/1 считывает с потока один символ, используя синхронный ввод (если ввод осуществляется с клавиатуры, то функция не начнет работу, пока пользователь не нажмет Enter);

    Но мой взгляд, достаточно удобно обрабатывать строки на SWI Prolog в виде списка кодов символов (они хранятся при этом в юникоде). Для ввода строк я использую вот функцию rd_line:

    %% считывает список кодов с текущего устройства ввода
    rd_line(Str):-
    	get_code(H), (
    		code_type(H, end_of_line), !, Str = [];
    		code_type(H, end_of_file), !, Str = [];
    		Str = [H|T], rd_line(T)
    	).

    Тут вызывается функция get_code, возвращающая код символа (аналогично get_char). Если текущий символ представляет собой конец строки или файла — результатом является пустая строка (пустой список кодов). В противном случае выполняется рекурсивный вызов для считывания остальных символов.

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

    • see/1, принимает ‘имя файла’, открывает файл для чтения, устанавливает его в качестве текущего потока ввода. После вызова предиката весь ввод осуществляется с открытого файла;
    • seen/0, закрывает файл, ассоциированный с текущим потоком ввода. После вызова этого предиката ввод осуществляется с клавиатуры;
    • tell/1, тоже самое, что see, но открывает файл для записи и устанавливает в качестве потока вывода;
    • told/0, закрывает файл открытый tell. После вызова, весь вывод попадает на экран.

    Такой вариант не сработает если вам надо работать одновременно с несколькими файлами. В этом случае надо использовать версии функции read, get_char и т.п., принимающие имя открытого файлового потока в качестве дополнительного аргумента. Открыть потом можно функцией open, а закрыть — close, работа с потоками в SWI Prolog мало отличается от других языков.

    В вашем случае строки не считывались, т.к. вы используете функцию read, которая считывает термы. Поставьте точки в конце строк и она их считает.

Для ответа в этой теме необходимо авторизоваться.