我想阅读像test.txt
这样的文字文件:
birthbook(tom,9,1).
birthbook(add,9,1).
birthbook(ddd,8,1).
代码:
test:-
open('test.txt', read, Str),
read_file(Str,Lines),
close(Str),
write(Lines), nl.
read_file(Stream,[]) :-
at_end_of_stream(Stream).
read_file(Stream,[X|L]) :-
\+ at_end_of_stream(Stream),
read(Stream,X),
read_file(Stream,L).
然而,它表明了这一点 错误:test.txt:1:4:语法错误:意外的文件结束。
答案 0 :(得分:1)
我在您的实施中看到了一些问题。首先,{/ 1}仅在之后才成功已经尝试读取文件中的最后一行。它不会告诉您是否即将阅读结束。因此,在读取最后一行之后,您的谓词将执行流读取,在 while ( getline(fileStream, input) )
text += input + L'\n';
成功之前使用at_end_of_stream/1
实例化X
。 (这类似于标准C库中end_of_file
函数的行为,资深C程序员会告诉您不要使用它。)
第二个问题是,当at_end_of_stream/1
成功时,你不会处理这种情况。
您可以按如下方式重构代码:
feof(.)
快速测试得出:
at_end_of_stream/1
答案 1 :(得分:1)
作为控制Prolog特殊执行流程的一个例子,考虑如何将read / 2(一个不可回溯的内置函数)转换成适合findall / 3的内容:
read_one_term(S, B) :-
repeat,
read(S, B),
( B = end_of_file, !, fail ; true ).
?- open('book.pl', read, S), findall(B, read_one_term(S, B), L), close(S).
S = <stream>(0x7f51b00b3340),
L = [birthbook(tom, 9, 1), birthbook(add, 9, 1), birthbook(ddd, 8, 1)].