简体   繁体   中英

Reading from textfile in prolog

I have some trouble with reading from text files in GNU Prolog. I want to read a.txt file and move the file to a list. I have tried to follow some previous examples on stackoverflow to read the file, but have not been able to access the file (it seems). Here is what I've got so far:

readFile:-
    open('text.txt', read, File),
    read_lines(File, Lines),
    close(File),
    write(Lines), nl.

read_lines(File,[]):- 
    at_end_of_stream(File).

read_lines(File,[X|L]):-
    \+ at_end_of_stream(File),
    read(File,X),
    read_lines(File,L).

When I try to call: ?- readFile. gives me an errormessage: uncaught exception: error(syntax_error('text.txt:2 (char:1). or operator expected after expression'),read/2) .

Thanks in advance!

Edit: As provided by David, GNU Prolog's Character input/output library and get_char worked for me!

Working code:

readFile:-
    open('text.txt', read, File),
    read_lines(File, Lines),
    close(File),
    write(Lines), nl.

read_lines(File,[]):- 
    at_end_of_stream(File).

read_lines(File,[X|L]):-
    \+ at_end_of_stream(File),
    get_char(File,X),
    read_lines(File,L).

You can improve on your edit answer a bit. First note that the read_line/2 predicate name is misleading. You're reading a text file to a list of characters, not to a list of individual lines. You're also calling the at_end_of_stream/1 predicate twice and creating a spurious choice-point at each call to your read_lines /2 predicate. Moreover, the at_end_of_stream/1 predicate, albeit a standard predicate, doesn't have a reliable implementation in all Prolog systems. A possible rewrite of your code is:

read_file(File, Chars) :-
    open(File, read, Stream),
    get_char(Stream, Char),
    read_file(Stream, Char, Chars),
    close(Stream).

read_file(Stream, Char, Chars) :-
    (   Char == end_of_file ->
        Chars = []
    ;   Chars = [Char| Rest],
        get_char(Stream, Next),
        read_file(Stream, Next, Rest)
    ).

Now that your intent is clearer, the same functionality can be accomplished using the Logtalk reader library with a single call:

reader::file_to_chars(File, Chars)

But, if learning is is your primary goal, writing your own solutions instead of relying on existing libraries is a good choice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM