用序言将行读入列表 [英] reading lines into lists with prolog
问题描述
我有一个包含一些信息的文本文件,每一行都是一个值列表.我想阅读每一行并将其与其他所有行一起存储在列表中. 这是我到目前为止的代码
I have a text file with some information, each line is a list of values. I want to read each line and store it in a list with all the other lines. This is the code I have so far
getLines:-
open('textFile.abc', read, Source),
readData(Source,DataList),
write(DataList).
readData(Source,DataList):-
read(Source,NewLine),
NewLine== end_of_file -> fail;true,
readData(Source,[DataList|NewLine]).
readData(Source,[DataList|end_of_file]).
这是文本文件'textfile.abc'
this is the text file 'textfile.abc'
[0.45,20,850,900,3].
[0.45,20,850,900,2].
[0.45,20,850,900,1].
当我运行getLines时,它将执行并写入'_G1147068'而不是项目列表. 我不确定我在这里做错了什么,任何帮助将不胜感激.
When I run getLines it executes and writes '_G1147068' instead of the list of items. I'm not sure what I'm doing wrong here, any help would be appreciated.
推荐答案
在readData/2
的第二个子句中找到代码无法按预期方式工作的主要原因(如下所述).它包含两个单例变量,并且[DataList|end_of_file]
不是列表(因为end_of_file
是原子).
The main reason why your code does not work the way you intend it to is found in the second clause of readData/2
(quoted below). It contains two singleton variables and [DataList|end_of_file]
is not a list (since end_of_file
is an atom).
readData(Source,[DataList|end_of_file]).
您的代码也可以通过其他方式进行改进:
Your code can be improved in other ways as well:
- 您打开了一个流,但是从不关闭它:您可以为此使用
close/1
. - 即使您在
readData/2
成功之后关闭流,也要假设您的程序在运行readData/2
时抛出异常或失败.现在将无法访问close/1
,并且流仍将打开.幸运的是,有setup_call_cleanup/3
可以关闭流,即使您的代码失败/引发异常也是如此. - 由于您正在读取的数据恰好是Prolog术语,因此您可以使用
read_term/3 "rel =" nofollow>很多不错的选择. - 请注意,在列表构造
L = [H|T]
中,我确保T
始终是列表.
- You open a stream but you never close it: you can use
close/1
for this. - Even if you close the stream after
readData/2
succeeds, suppose your program throws an exception or fails while runningreadData/2
. Nowclose/1
will not be reached and the stream will still be open. Luckily, there issetup_call_cleanup/3
which closes the stream even if your code fails / throws an exception. - Since the data you are reading happens to be Prolog terms, you can use
read_term/3
which comes with many nice options. - Notice that in list construction
L = [H|T]
I make sure theT
is always a list.
结果代码:
getLines(L):-
setup_call_cleanup(
open('textFile.abc', read, In),
readData(In, L),
close(In)
).
readData(In, L):-
read_term(In, H, []),
( H == end_of_file
-> L = []
; L = [H|T],
readData(In,T)
).
希望这对您有所帮助!
这篇关于用序言将行读入列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!