我有一个文件memo.dat
,其内容如下:
memo(verdi,11).
memo(rossi,7).
memo(bianchi,9).
memo(blu,7).
memo(neri,11).
memo(carli,11).
memo(rapini,8).
我编写了一个prolog程序,以便从该文件中获取一组元组:
memo_to_list(MemoList):-
open('/home/ale/Downloads/Prolog_exercises/memo.dat',read,Stream),
read_list_from_stream(Stream,MemoList),
close(Stream).
read_list_from_stream(Stream,[]):-
at_end_of_stream(Stream),!.
read_list_from_stream(Stream,[(Cognome,Ora)|RestoAppuntamenti]):-
read(Stream,memo(Cognome,Ora)),
read_list_from_stream(Stream,RestoAppuntamenti).
但是,谓词at_end_of_stream
无法检查流何时到达末尾。可能是什么问题? (我使用ubuntu默认文本编辑器来创建文件memo.dat
)
答案 0 :(得分:1)
仅当您实际到达流的末尾时,才会检测到它。当您读取最后一个事实时,文件末尾标记尚未读取。试试类似的东西:
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标准要求在结束词的.
后面加上布局字符。仅当上一个词的最后一个点之后没有任何字符(文件末尾除外)时,您的代码才有效,这会使Prolog文本不符合要求,但根据Prolog系统的不同,可能允许结尾阅读最后一项后,通过调用at_end_of_stream /1
谓词来检测要检测的流的数量。还请注意,如果保存时不存在文本编辑器,则通常在文本的最后一行之后添加换行符。该换行符是Prolog标准所要求的布局字符。因此,对于兼容,可靠且可移植的解决方案,请确保数据文件末尾有新行,并在此答案中使用解决方案。