Search code examples
prologgnu-prolog

How to use read_line_to_codes & atom_codes iteratively to generate array of lines as strings of my .txt file?


I am trying to use read_line_to_codes(Stream,Result) and atom_codes(String,Result). These two predicates first, read line from file as an array of char codes, and then convert this array back to string. Then I would like to input all those strings to an array of Strings.

I tried the recursive approach but have trouble with how to actually instantiate the array to empty in the beginning, and what would be the terminating condition of process_the_stream/2.

/*The code which doesn't work.. but the idea is obvious.*/

process_the_stream(Stream,end_of_file):-!.
process_the_stream(Stream,ResultArray):-
        read_line_to_codes(Stream,CodeLine),
        atom_codes(LineAsString,CodeLine),
        append_to_end_of_list(LineAsString,ResultArray,TempList),
        process_the_stream(Stream,TempList).

I expect a recursive approach to get array of lines as strings.


Solution

  • Follows a Logtalk-based portable solution that you can use as-is with most Prolog compilers, including GNU Prolog, or adapt to your own code:

    ---- processor.lgt ----
    :- object(processor).
    
        :- public(read_file_to_lines/2).
    
        :- uses(reader, [line_to_codes/2]).
    
        read_file_to_lines(File, Lines) :-
            open(File, read, Stream),
            line_to_codes(Stream, Codes),
            read_file_to_lines(Codes, Stream, Lines).
    
        read_file_to_lines(end_of_file, Stream, []) :-
            !,
            close(Stream).
        read_file_to_lines(Codes, Stream, [Line| Lines]) :-
            atom_codes(Line, Codes),
            line_to_codes(Stream, NextCodes),
            read_file_to_lines(NextCodes, Stream, Lines).
    
    :- end_object.
    -----------------------
    

    Sample file for testing:

    ------ file.txt -------
    abc def ghi
    jlk mno pqr
    -----------------------
    

    Simple test:

    $ gplgt
    ...
    
    | ?- {library(reader_loader), processor}.
    ...
    
    | ?- processor::read_file_to_lines('file.txt', Lines).
    
    Lines = ['abc def ghi','jlk mno pqr']
    
    yes