Read a file line by line in Prolog

2019-01-06 19:34发布

问题:

I'd like to read a plain text file and apply a predicate to each line (the predicates contain write which does the output). How would I do that?

回答1:

In SWI-Prolog, the cleanest solution is to write a DCG that describes what a "line" is, then call a predicate for each line. Use library(pio) to apply the DCG to a file.

EDIT: As requested, consider:

:- use_module(library(pio)).

lines([])           --> call(eos), !.
lines([Line|Lines]) --> line(Line), lines(Lines).

eos([], []).

line([])     --> ( "\n" ; call(eos) ), !.
line([L|Ls]) --> [L], line(Ls).

Sample usage: ?- phrase_from_file(lines(Ls), 'your_file.txt').



回答2:

You can use read to read the stream. Remember to invoke at_end_of_stream to ensure no syntax errors.

Example:

readFile.pl

main :-
    open('myFile.txt', read, Str),
    read_file(Str,Lines),
    close(Str),
    write(Lines), nl.

read_file(Stream,[]) :-
    at_end_of_stream(Stream).

read_file(Stream,[X|L]) :-
    \+ at_end_of_stream(Stream),
    read(Stream,X),
    read_file(Stream,L).

myFile.txt

'line 0'.
'line 1'.
'line 2'.
'line 3'.
'line 4'.
'line 5'.
'line 6'.
'line 7'.
'line 8'.
'line 9'.

Thus by invoking main you will recieve the output:

?- main.
[line 0,line 1,line 2,line 3,line 4,line 5,line 6,line 7,line 8,line 9]
true 

Just configure main. The output here is an example by using write, of course. Configure to match your request.

I assume that this principle can be applied to answer your question. Good luck.