Конец потока обнаруживается только тогда, когда вы действительно его достигаете. Когда вы читаете последний факт, маркер конца файла еще не прочитан. Вместо этого попробуйте что-то вроде:
memo_to_list(MemoList):-
open('/home/ale/Downloads/Prolog_exercises/memo.dat',read,Stream),
read(Stream,Term),
read_list_from_stream(Term,Stream,MemoList),
close(Stream).
read_list_from_stream(end_of_file,_,[]) :-
!.
read_list_from_stream(memo(Cognome,Ora),Stream,[(Cognome,Ora)|RestoAppuntamenti]):-
read(Stream,Term),
read_list_from_stream(Term,Stream,RestoAppuntamenti).
Вы также можете избежать утечки дескрипторов потоков и незакрытых потоков в случае, если что-то не так с вашим файлом данных, используя встроенный предикат setup_call_cleanup/3
:
memo_to_list(MemoList) :-
setup_call_cleanup(
open('/Users/pmoura/Desktop/memo.dat',read,Stream),
( read(Stream,Term),
read_list_from_stream(Term,Stream,MemoList)
),
close(Stream)
).
Обновить
Стандарт Prolog требует, чтобы за .
, заканчивающим термин, следовал символ макета. Ваш код работает только в том случае, если нет никакого символа (кроме конца файла) после последней точки последнего термина, что делает текст Пролога несоответствующим, но, в зависимости от системы Пролога, может разрешить конец потока, который нужно обнаружить, вызвав предикат at_end_of_stream /1
после чтения последнего термина. Также обратите внимание, что текстовые редакторы обычно добавляют новую строку после последней строки текста, если она отсутствует при сохранении. Эта новая строка является символом макета, как того требует стандарт Пролога. Поэтому для совместимого, надежного и переносимого решения убедитесь, что в конце файла данных есть новая строка, и используйте решение вместе с этим ответом.
person
Paulo Moura
schedule
28.08.2018