Input Procedures - MIT/GNU Scheme 7.7.90+
Description: MIT/GNU Scheme 7.7.90+

Next: Output Procedures, Previous: String Ports, Up: Input/Output

### 14.4 Input Procedures

This section describes the procedures that read input. Input procedures can read either from the current input port or from a given port. Remember that to read from a file, you must first open a port to the file.

Input ports can be divided into two types, called interactive and non-interactive. Interactive input ports are ports that read input from a source that is time-dependent; for example, a port that reads input from a terminal or from another program. Non-interactive input ports read input from a time-independent source, such as an ordinary file or a character string.

All optional arguments called input-port, if not supplied, default to the current input port.

— procedure: read-char [input-port]

> Returns the next character available from input-port, updating input-port to point to the following character. If no more characters are available, an end-of-file object is returned.

> In MIT/GNU Scheme, if input-port is an interactive input port and no characters are immediately available, `read-char` will hang waiting for input, even if the port is in non-blocking mode.

— procedure: peek-char [input-port]

> Returns the next character available from input-port, without updating input-port to point to the following character. If no more characters are available, an end-of-file object is returned.1

> In MIT/GNU Scheme, if input-port is an interactive input port and no characters are immediately available, `peek-char` will hang waiting for input, even if the port is in non-blocking mode.

— procedure: char-ready? [input-port]

> Returns `#t` if a character is ready on input-port and returns `#f` otherwise. If `char-ready?` returns `#t` then the next `read-char` operation on input-port is guaranteed not to hang. If input-port is a file port at end of file then `char-ready?` returns `#t`.2

— procedure: read [input-port [environment]]

> Converts external representations of Scheme objects into the objects themselves. `read` returns the next object parsable from input-port, updating input-port to point to the first character past the end of the written representation of the object. If an end of file is encountered in the input before any characters are found that can begin an object, `read` returns an end-of-file object. The input-port remains open, and further attempts to read will also return an end-of-file object. If an end of file is encountered after the beginning of an object's written representation, but the written representation is incomplete and therefore not parsable, an error is signalled.

> Environment is used to look up the values of control variables such as ``*parser-radix*`'. If not supplied, it defaults to the REP environment.

— procedure: eof-object? object

> Returns `#t` if object is an end-of-file object; otherwise returns `#f`.

— procedure: read-char-no-hang [input-port]

> If input-port can deliver a character without blocking, this procedure acts exactly like `read-char`, immediately returning that character. Otherwise, `#f` is returned, unless input-port is a file port at end of file, in which case an end-of-file object is returned. In no case will this procedure block waiting for input.

— procedure: read-string char-set [input-port]

> Reads characters from input-port until it finds a terminating character that is a member of char-set (see Character Sets) or encounters end of file. The port is updated to point to the terminating character, or to end of file if no terminating character was found. `read-string` returns the characters, up to but excluding the terminating character, as a newly allocated string.

> This procedure ignores the blocking mode of the port, blocking unconditionally until it sees either a delimiter or end of file. If end of file is encountered before any characters are read, an end-of-file object is returned.

> On many input ports, this operation is significantly faster than the following equivalent code using `peek-char` and `read-char`:

>               (define (read-string char-set input-port)
>                 (let ((char (peek-char input-port)))
>                   (if (eof-object? char)
>                       char
>                       (list->string
>                        (let loop ((char char))
>                          (if (or (eof-object? char)
>                                  (char-set-member? char-set char))
>                              '()
>                              (begin
>                                (read-char input-port)
>                                (cons char
>                                      (loop (peek-char input-port))))))))))

— procedure: read-line [input-port]

> `read-line` reads a single line of text from input-port, and returns that line as a newly allocated string. The `#\newline` terminating the line, if any, is discarded and does not appear in the returned string.

> This procedure ignores the blocking mode of the port, blocking unconditionally until it has read an entire line. If end of file is encountered before any characters are read, an end-of-file object is returned.

— procedure: read-string! string [input-port]
— procedure: read-substring! string start end [input-port]

> `read-string!` and `read-substring!` fill the specified region of string with characters read from input-port until the region is full or else there are no more characters available from the port. For `read-string!`, the region is all of string, and for `read-substring!`, the region is that part of string specified by start and end.

> The returned value is the number of characters filled into the region. However, there are several interesting cases to consider:

> - If `read-string!` (`read-substring!`) is called when input-port is at “end-of-file”, then the returned value is `0`. Note that “end-of-file” can mean a file port that is at the file's end, a string port that is at the string's end, or any other port that will never produce more characters.
> - If input-port is an interactive port (e.g. a terminal), and one or more characters are immediately available, the region is filled using the available characters. The procedure then returns immediately, without waiting for further characters, even if the number of available characters is less than the size of the region. The returned value is the number of characters actually filled in.
> - If input-port is an interactive port and no characters are immediately available, the result of the operation depends on the blocking mode of the port. If the port is in non-blocking mode, `read-string!` (`read-substring!`) immediately returns the value `#f`. Otherwise, the operation blocks until a character is available. As soon as at least one character is available, the region is filled using the available characters. The procedure then returns immediately, without waiting for further characters, even if the number of available characters is less than the size of the region. The returned value is the number of characters actually filled in.

> The importance of `read-string!` and `read-substring!` are that they are both flexible and extremely fast, especially for large amounts of data.

The following variables may be bound or assigned to change the behavior of the `read` procedure. They are looked up in the environment that is passed to `read`, and so may have different values in different environments. It is recommended that the global bindings of these variables be left unchanged; make local changes by shadowing the global bindings in nested environments.

— variable: *parser-radix*

> This variable defines the radix used by the reader when it parses numbers. This is similar to passing a radix argument to `string->number`. The value of this variable must be one of `2`, `8`, `10`, or `16`; any other value is ignored, and the reader uses radix `10`.

> Note that much of the number syntax is invalid for radixes other than `10`. The reader detects cases where such invalid syntax is used and signals an error. However, problems can still occur when `*parser-radix*` is set to `16`, because syntax that normally denotes symbols can now denote numbers (e.g. `abc`). Because of this, it is usually undesirable to set this variable to anything other than the default.

> The default value of this variable is `10`.

— variable: *parser-canonicalize-symbols?*

> This variable controls how the parser handles case-sensitivity of symbols. If it is bound to its default value of `#t`, symbols read by the parser are converted to lower case before being interned. Otherwise, symbols are interned without case conversion.

> In general, it is a bad idea to use this feature, as it doesn't really make Scheme case-sensitive, and therefore can break features of the Scheme runtime that depend on case-insensitive symbols.

#### Footnotes

[1] The value returned by a call to `peek-char` is the same as the value that would have been returned by a call to `read-char` on the same port. The only difference is that the very next call to `read-char` or `peek-char` on that input-port will return the value returned by the preceding call to `peek-char`. In particular, a call to `peek-char` on an interactive port will hang waiting for input whenever a call to `read-char` would have hung.

[2] `char-ready?` exists to make it possible for a program to accept characters from interactive ports without getting stuck waiting for input. Any input editors associated with such ports must make sure that characters whose existence has been asserted by `char-ready?` cannot be rubbed out. If `char-ready?` were to return `#f` at end of file, a port at end of file would be indistinguishable from an interactive port that has no ready characters.