从GNU Prolog的文件中读取一行 [英] Reading a line from a file in GNU Prolog

查看:140
本文介绍了从GNU Prolog的文件中读取一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得我用我认为应该很容易的东西把我的头撞在墙上。也许我的做法是不正确的。我绝对不觉得我理解Prolog背后的I / O概念。 (比如:流别名和变量绑定的open / 3之间有什么区别?)但是我离题了:

如何做一个文件读取一行在GNU Prolog的线? (所以不能访问SWI所具有的方便的功能。)我认为它与get_char / 1和peek_char / 1(检查终止的换行符)有关,但是我尝试实现一个可行的解决方案迄今为止失败了。 / p>

这里是我得到的:

  readl_as_list ID,X): -  
current_input(ID),
readl_as_list(X)。

readl_as_list([X]): -
(peek_char(NextChar),==(NextChar,'\\\
');
get_code(Char1),
append([X],[Char1],X),
readl_as_list(X))。

printl_list([]): -
!,nl。
printl_list([H | X]): -
put_code(H),printl_list(X)。

将这个加载到解释器中,我得到了(空行为了便于阅读):

  |打开('word_list.txt',阅读,ID)。 
ID ='$ stream'(2)

| - readl_as_list(ID,X)。
ID ='$ stream'(0)
X = [_]?
%(口译员暂停,直到我按回车)

| ? - printl_list(X)。
X = []

这些行不一定非得以字符列表的形式阅读,但是因为我的目标是搜索匹配某些条件(例如不重复的字母)的单词列表,所以这似乎是最明智的做法。

解决方案

我写了一个实用程序,获取一行代码。返回end_of_file结束...

  read_line_codes(S,SoFar,L): -  
get_code(S,C ),
(C == -1
- >(SoFar == []
- > L = end_of_file
; reverse(SoFar,L)

;(C == 0'\ $
→> reverse(SoFar,L)
; read_line_codes(S,[C | SoFar],L)

)。

测试:

 < ('data_grid.pl',read,S),repeat,read_line_codes(S,[],L),format('〜s',[L])。 
/ *文件:data_grid.pl
S =< stream>(0x335c9e0),
L = [47,42,32,32,70,105,108,101,58 | ...];
作者:Carlo ,,,
S =< stream>(0x335c9e0),
L = [32,32,32,32,65,117,116,104,111 | ..];
创建时间:2011年10月20日
S = (0x335c9e0),
L = [32,32, 。];
...


I feel like I'm bashing my head against a wall with something that I assume should be easy. Perhaps my approach is incorrect. I definitely don't feel like I understand the concept behind I/O in Prolog. (Such as: what is the difference between a stream alias and the variable bound by open/3?) But I digress:

How do a read a file line-by-line in GNU Prolog? (So without access to the handy functions that SWI has.) I assume it has something to do with get_char/1 and peek_char/1 (to check for a terminating newline) but my attempts to implement a workable solution have failed so far.

Here is as far as I've gotten:

readl_as_list(ID, X):-
    current_input(ID),
    readl_as_list(X).

readl_as_list([X]):-
    (peek_char(NextChar), ==(NextChar, '\n'); 
        get_code(Char1),
        append([X], [Char1], X),
        readl_as_list(X)).

printl_list([]):-
    !, nl.
printl_list([H|X]):-
    put_code(H), printl_list(X).

Loading this into the interpreter, I get (empty lines removed for readability):

| ?- open('word_list.txt', read, ID).
ID = '$stream'(2)
yes
| ?- readl_as_list(ID, X).
ID = '$stream'(0)
X = [_] ? 
% (interpreter pauses until I press return)
yes
| ?- printl_list(X).
X = []
yes

The lines don't necessarily have to be read in as character lists, but since my goal is to search through a list of words for ones that match certain conditions (no repeat letters, for example), that seemed the most sensible way to do it.

解决方案

I wrote an utility, that fetch a line of codes. Returns end_of_file at end...

read_line_codes(S, SoFar, L) :-
    get_code(S, C),
    (   C == -1
    ->  (  SoFar == []
        ->  L = end_of_file
        ;   reverse(SoFar, L)
        )
    ;   (  C == 0'\n
        -> reverse(SoFar, L)
        ;  read_line_codes(S, [C|SoFar], L)
        )
    ).

test:

?- open('data_grid.pl',read,S),repeat,read_line_codes(S,[],L),format('~s',[L]).
/*  File:    data_grid.pl
S = <stream>(0x335c9e0),
L = [47, 42, 32, 32, 70, 105, 108, 101, 58|...] ;
    Author:  Carlo,,,
S = <stream>(0x335c9e0),
L = [32, 32, 32, 32, 65, 117, 116, 104, 111|...] ;
    Created: Oct 20 2011
S = <stream>(0x335c9e0),
L = [32, 32, 32, 32, 67, 114, 101, 97, 116|...] ;
...

这篇关于从GNU Prolog的文件中读取一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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