如何在prolog中读取文件?

如何在prolog中读取文件?,prolog,Prolog,我想读一个文本文件,如test.txt: birthbook(tom,9,1). birthbook(add,9,1). birthbook(ddd,8,1). 代码: 然而,它表明 错误:test.txt:1:4:语法错误:意外的文件结尾。我发现您的实现存在一些问题。首先,只有在尝试读取文件中的最后一行之后,\u stream/1的\u end\u处的才会成功。它不会告诉你是否要读到结尾。因此,您的谓词将在读取最后一行之后执行流读取,在成功执行\u stream/1的\u end\u之前,使

我想读一个文本文件,如
test.txt

birthbook(tom,9,1).
birthbook(add,9,1).
birthbook(ddd,8,1).
代码:

然而,它表明
错误:test.txt:1:4:语法错误:意外的文件结尾。

我发现您的实现存在一些问题。首先,只有在尝试读取文件中的最后一行之后,\u stream/1的\u end\u处的
才会成功。它不会告诉你是否要读到结尾。因此,您的谓词将在读取最后一行之后执行流读取,在成功执行\u stream/1的\u end\u之前,使用\u file的
end\u实例化
X
。(这类似于标准C库中的
feof(.)
函数的行为,资深C程序员会告诉您避免使用该函数。)

第二个问题是当\u stream/1
的\u end\u中的
成功时,您没有注意到这种情况

您可以按如下方式重构代码:

read_file(Stream, Lines) :-
    read(Stream, Line),               % Attempt a read Line from the stream
    (  at_end_of_stream(Stream)       % If we're at the end of the stream then...
    -> Lines = []                     % ...lines read is empty
    ;  Lines = [Line|NewLines],       % Otherwise, Lines is Line followed by
       read_file(Stream, NewLines)    %   a read of the rest of the file
    ).
快速测试产生:

?- open('test.txt', read, Str), read_file(Str, Lines), close(Str), write(Lines), nl.
Str = <stream>(0x871c410),
Lines = [birthbook(tom, 9, 1), birthbook(add, 9, 1), birthbook(ddd, 8, 1)].

?-
?-打开('test.txt',读取,Str),读取文件(Str,行),关闭(Str),写入(行),nl。
Str=(0x871c410),
行=[出生簿(tom,9,1),出生簿(add,9,1),出生簿(ddd,8,1)]。
?-

< /代码>

作为控制Prolog特有执行流的一个例子,考虑如何将读/ 2非回溯建置变成适合FANDALL/3:< /P>的一种方法。

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)].
读取一个术语(S,B):-
重复一遍,
读(S,B),
(B=文件的结尾,!,失败;真)。
?打开('book.pl',读取,S),findall(B,读取一个术语(S,B),L),关闭(S)。
S=(0x7F51B000B3340),
L=[出生簿(汤姆,9,1),出生簿(加,9,1),出生簿(ddd,8,1)]。
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)].