Next: Customizing Read Up: Ports Previous: Custom Ports

## Reading and Printing

In addition to the standard reading procedures, MzScheme provides `read-line`, `read-string`, `read-string-avail!`, and `read-string-avail!/enable-break`:

- `(read-line [input-port mode-symbol])` returns a string containing the next line of characters from input-port. If input-port is omitted, the current input port is used.

  Characters are read from input-port until a line separator or an end-of-file is read. The line separator is not included in the result string (but it is removed from the port's stream). If no characters are read before an end-of-file is encountered, `eof` is returned.

  The mode-symbol argument determines the line separator(s). It must be one of the following symbols:

  - `'linefeed` breaks lines on linefeed characters; this is the default.
  - `'return` breaks lines on return characters.
  - `'return-linefeed` breaks lines on return-linefeed combinations. If a return character is not followed by a linefeed character, it is included in the result string; similarly, a linefeed that is not preceded by a return is included in the result string.
  - `'any` breaks lines on any of a return character, linefeed character, or return-linefeed combination. If a return character is followed by a linefeed character, the two are treated as a combination.
  - `'any-one` breaks lines on either a return or linefeed character, without recognizing return-linefeed combinations.

  Return and linefeed characters are detected after the conversions that are automatically performed when reading a file in text mode. For example, reading a file in text mode under Windows automatically changes return-linefeed combinations to a linefeed. Thus, when a file is opened in text mode, `'linefeed` is usually the appropriate `read-line` mode.
- `(read-string k [input-port])` returns a string containing the next k characters from input-port. The default value of input-port is the current input port.

  If k is `0`, then the empty string is returned. Otherwise, if fewer than k characters are available before an end-of-file is encountered, then the returned string will contain only those characters before the end-of-file (i.e., the returned string's length will be less than k). If no characters are available before an end-of-file, then `eof` is returned.

  If an error occurs during reading, some characters may be lost (i.e., if `read-string` successfully reads some characters before eoncountering an error, the characters are dropped.)

- `(read-string-avail! string [input-port start-k end-k])` reads characters from input-port and puts them into string starting from index start-k (inclusive) up to end-k (exclusive). The default value of input-port is the current input port. The default value of start-k is `0`. The default value of end-k is the length of the string. Like `substring`, the `exn:application:mismatch` exception is raised if start-k or end-k is out-of-range for string.

  If the difference between start-k and end-k is `0`, then `0` is returned and the string is not modified. If no characters are available before an end-of-file, then `eof` is returned. Otherwise, the return value is the number of characters read. If m characters are read and m < end-k - start-k, then string is not modified at indices start-k + m though end-k.

  Unlike `read-string`, `read-string-avail!` returns without blocking after reading immediately-available characters. It blocks only if no characters are yet available. Also unlike `read-string`, `read-string-avail!` never drops characters; if `read-string-avail!` successfully reads some characters and then encounters an error, it suppresses the error (treating it roughly like an end-of-file) and returns the read characters. (The error will be triggered by future reads.) If an error is encountered before any characters have been read, an exception is raised.

  If input-port is a user port, then at most one character is read. This convention allows `read-string-avail!` to preserve its guarantees in the presence of exceptions raised by the user port's character-reading procedure.

- `(read-string-avail!/enable-break string [input-port start-k end-k])` is like `read-string-avail!`, except that breaks are enabled during the read. The procedure provides a guarantee about the interaction of reading and breaks: if breaking is disabled when `read-string-avail!/enable-break` is called, and if the `exn:misc:user-break` exception is raised as a result of the call, then no characters will have been read from input-port.

In addition to the standard printing procedures, MzScheme provides `print`, which outputs values to a port by calling the port's print handler (see section 11.1.9), `write-string-avail`, and `write-string-avail/enable-break`:

- `(print v [output-port])` outputs v to output-port. The default value of output-port is the current output port.

  The `print` procedure is used to print Scheme values in a context where a programmer expects to see a Scheme value. The rationale for providing `print` is that `display` and `write` both have standard output conventions, and this standardization restricts the ways that an environment can change the behavior of these procedures. No output conventions should be assumed for `print` so that environments are free to modify the actual output generated by `print` in any way. Unlike the port display and write handlers, a global port print handler can be installed through the `global-port-print-handler` parameter (see section 9.4.1.2).

- `(write-string-avail string [output-port start-k end-k])` write characters to output-port from string starting from index start-k (inclusive) up to end-k (exclusive). The default value of output-port is the current output port. The default value of start-k is `0`. The default value of end-k is the length of the string. Like `substring`, the `exn:application:mismatch` exception is raised if start-k or end-k is out-of-range for string.

  The result is the number of characters written and flushed to output-port. The `write-string-avail` procedure returns without blocking after writing as many characters as it can immediately flush. It blocks only if no characters can be flushed immediately.

  The `write-string-avail` procedure never drops characters; if `write-string-avail` successfully writes some characters and then encounters an error, it suppresses the error and returns the number of written characters. (The error will be triggered by future writes.) If an error is encountered before any characters have been written, an exception is raised.

- `(write-string-avail/enable-break string [input-port start-k end-k])` is like `write-string-avail`, except that breaks are enabled during the write. The procedure provides a guarantee about the interaction of writing and breaks: if breaking is disabled when `write-string-avail/enable-break` is called, and if the `exn:misc:user-break` exception is raised as a result of the call, then no characters will have been written to output-port.

Formatted output is written to a port with `fprintf`:

- `(fprintf output-port format-string v )` prints formatted output to output-port, where format-string is a string that is printed; format-string can contain special formatting tags:
  - `~`n or `~`% prints a newline
  - `~`a or `~`A `display`s the next argument among the vs
  - `~`s or `~`S `write`s the next argument among the vs
  - `~`v or `~`V `print`s the next argument among the vs
  - `~`e or `~`E outputs the next argument among the vs using the current error value conversion handler (see section 9.4.1.9) and current error printing width
  - `~`c or `~`C `write-char`s the next argument in vs; if the next argument is not a character, the `exn:application:mismatch` exception is raised
  - `~`b or `~`B prints the next argument among the vs in binary; if the next argument is not an exact number, the `exn:application:mismatch` exception is raised
  - `~`o or `~`O prints the next argument among the vs in octal; if the next argument is not an exact number, the `exn:application:mismatch` exception is raised
  - `~`x or `~`X prints the next argument among the vs in hexadecimal; if the next argument is not an exact number, the `exn:application:mismatch` exception is raised
  - `~``~` prints a tilde (~)
  - `~`w, where w is a whitespace character, skips characters in format-string until a non-whitespace character is encountered or until a second end-of-line is encountered (whichever happens first). An end-of-line is either `#\return`, `#\newline`, or `#\return` followed immediately by `#\newline` (on all platforms).

  The return value is void.

- `(printf format-string v )` same as `fprintf` with the current output port.
- `(format format-string v )` same as `fprintf` with a string output port where the final string is returned as the result.

When an illegal format string is supplied to one of these procedures, the `exn:application:type` exception is raised. When the format string requires more additional arguments than are supplied, the `exn:application:fprintf:mismatch` exception is raised. When more additional arguments are supplied than are used by the format string, the `exn:application:mismatch` exception is raised.

For example, ``

      (fprintf port "~a as a string is ~s.~n" '(3 4) "(3 4)")

prints this message to port: `

      (3 4) as a string is "(3 4)".

` followed by a newline.

Next: Customizing Read Up: Ports Previous: Custom Ports