用序言将行读入列表 [英] reading lines into lists with prolog

查看:69
本文介绍了用序言将行读入列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一些信息的文本文件,每一行都是一个值列表.我想阅读每一行并将其与其他所有行一起存储在列表中. 这是我到目前为止的代码

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 running readData/2. Now close/1 will not be reached and the stream will still be open. Luckily, there is setup_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 the T 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆