从GNU Prolog中的文件中读取一行

时间:2012-11-28 21:51:31

标签: file-io prolog 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, '\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).

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

| ?- 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

这些行不一定要作为字符列表读入,但由于我的目标是搜索符合某些条件(例如,没有重复字母)的单词列表,这似乎是最明智的这样做的方法。

1 个答案:

答案 0 :(得分:2)

我写了一个实用程序,它获取一行代码。在end ...返回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'\n
        -> reverse(SoFar, L)
        ;  read_line_codes(S, [C|SoFar], L)
        )
    ).

试验:

?- 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|...] ;
...