A string of characters is read from the input stream Stream, up to a delimiter, ignoring any padding around the data. More precisely, the predicate performs the following steps:
* Skip all characters that match one of the PadChars.
* Read up to a character that matches one of SepChars or end of file.
* Discard trailing characters that match one of the PadChars
from the collected input.
* Unify String with a string created from the input, and Separator
with the code of the actual separator character consumed (or -1
if the input was terminated by the end of the stream).
Both SepChars and PadChars are strings which are interpreted as sets of
characters. I.e. any character that occurs in SepChars is a separator,
and any character that occurs in PadChars is a padding character.
In addition, two symbolic SepChars can be specified (as atoms):
end_of_line a LF or CR/LF sequence (returned Separator is LF (10))
end_of_file the end of the file/input (returned Separator is -1)
End of file always acts like a delimiter, therefore end_of_file means
the same as the empty Separator string.
If the last characters read are terminated by the end of the stream, the predicate returns those characters and a Separator of -1, leaving the stream position 'at' end-of-stream. The next read attempt then returns an empty string and a Separator of -1, leaving the stream position 'past' end-of-stream. If the stream has the eof_action(error) property, a further read attempt will raise the event 'Trying to read past the end of the stream' (198).
Note: This predicate provides functionality similar to split_string/4, except that SepChars and PadChars must not be partially overlapping (as this would require lookahead and could cause unexpected blocking read).
% read one line from the input stream
?- read_string(input, end_of_line, "", End, String).
hello world!
End = 10
String = "hello world!"
Yes (0.00s cpu)
% read input until end of file
?- read_string(input, end_of_file, "", End, String).
abc
def
^D
End = -1
String = "abc\ndef\n"
Yes (0.00s cpu)
% Separators and padding
?- read_string(input, ",;", ".", Sep1, String1),
read_string(input, ",;", ".", Sep2, String2),
read_string(input, ",;", ".", Sep3, String3).
...abc...def...;,...ghi...
^D
Sep1 = 59
String1 = "abc...def"
Sep2 = 44
String2 = ""
Sep3 = -1
String3 = "ghi...\n"
Yes (0.00s cpu)
% End of stream
?- read_string(input, ",", "", Sep1, String1),
read_string(input, ",", "", Sep2, String2),
read_string(input, ",", "", Sep3, String3).
abc,def
^D
Sep1 = 44
String1 = "abc"
Sep2 = -1
String2 = "def\n"
Sep3 = -1
String3 = ""
Yes (0.00s cpu)
% Code example: read lines from a file and return
% a list of strings, each string containing a line
get_lines(File, Lines) :-
open(File, read, S),
(
fromto(0,_,Sep,-1),
foreach(Line,Lines),
param(S)
do
read_string(S, end_of_line, "", Sep, Line)
),
close(S).