Reading and Writing Lines -- library(lineio)

library(lineio) defines some commands for reading and writing lines of text.


get_line(-Chars, -Terminator)

reads characters from the current input stream until it finds an end-of-line character. Chars is unified with a list containing all the character codes other than the end-of-line character, and Terminator is unified with the end-of-line character. This allows you to check which character ended the line; in particular you should be prepared to handle the is_endfile(Terminator) case. When the end of a file is encountered, there may have been a partial line preceding it; so when is_endfile(Terminator), Chars may or may not be the empty list.

get_line/2 is normally called with Chars unbound. A call to get_line/2 with Chars bound will behave similarly to get0/1 in that even if the line of characters does not unify with Chars, nevertheless the entire line is consumed and is irretrievable. Thus, if you call get_line("fred", Eol) and the next line of input is in fact jim or frederica, the entire line will have been read before the call to get_line/2 fails. Only call get_line/2 with Chars bound when you want the line to be thrown away if it does not match. For example, if you want to skip until you encounter a line containing only a single . (a convention some editors and some mailers use for the end of terminal input), you can write

          ...
          skip_through_line(".")
          

where

          skip_through_line(X) :-
                  repeat,
                      get_line(X, _),
                  !.
          

(skip_through_line/1 is not in the library.)

get_line(-Chars)
is used for the common case in which you are uninterested in what the end-of-line character was, provided it was not end-of-file. get_line/1 reads a whole line, just like get_line/2, then checks that the line terminator was not the end-of-file character, and unifies the list of character codes with Chars. If Chars is instantiated and does not match the line that is read, or if the line terminator was end-of-file, get_line/1 fails quietly (with the same consequences regarding the loss of the non-matching text as with get_line/2 above).
fget_line(+Stream, ?Chars, ?Terminator)
like get_line/2 except that Stream is specified.
fget_line(+Stream, ?Chars)
like get_line/1 except that Stream is specified.
put_chars(+Chars)
is a generalization of put/1. Chars should be instantiated to a (possibly empty) list of character codes. The corresponding characters are written to the current output stream. If you know the characters in advance, it is better to use write/1; for example,
          put_chars("they do the same thing")
          

and

          write('they do the same thing')
          

both write exactly the same characters to the current output stream, but the latter is more efficient. Use put_chars/1 when you already have the text you want to write as a list of character codes, write/1 when you have the text as an atom.

put_line(+Chars)
writes the list of character codes Chars, then writes a newline character. It produces exactly the same output that
          put_chars(Chars), nl
          

would, but is generally more convenient. If you are reading lines from one file using get_line/1 and writing them to another, put_line/1 is the predicate to use.