[ Character I/O | Reference Manual | Alphabetic Index ]

# read_string(+Stream, +SepChars, +PadChars, -Separator, -String)

Reads a string from the stream Stream up to a delimiter.

Stream
  Stream handle or alias (atom)
SepChars
  String (set of characters) or atom
PadChars
  String (set of characters)
Separator
  Variable or integer character code
String
  Variable or string

## Description

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).

### Modes and Determinism

- read_string(+, +, +, -, -) is det

### Exceptions

(4) instantiation fault
  Stream, SepChars or PadChars is not instantiated.
(5) type error
  SepChars is not a string or atom.
(5) type error
  PadChars is not a string.
(6) out of range
  SepChars is an atom but not a valid symbolic delimiter.
(5) type error
  Stream is not an atom or handle.
(192) illegal stream mode
  Stream is not an input stream.
(193) illegal stream specification
  Stream is an illegal stream specification.
(198) reading past the file end
  Trying to read past the end of the stream.

## Examples

        % 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).

## See Also

get_char / 2, read_string / 3, read_token / 3, open / 3, open / 4