Input-Output (original) (raw)

Previous Contents Next


Input-output functions do calculate a value (often of type_unit_) but during their calculation they cause a modification of the state of the input-output peripherals: modification of the state of the keyboard buffer, outputting to the screen, writing in a file, or modification of a read pointer. The following two types are predefined: in_channel and _out_channel_for, respectively, input channels and output channels. When an end of file is met, the exception End_of_file is raised. Finally, the following three constants correspond to the standard channels for input, output, and error in Unix fashion: stdin,stdout, and stderr.

Channels

The input-output functions from the Objective CAML standard library manipulate communication channels: values of type_in_channel_ or out_channel. Apart from the three standard predefined values, the creation of a channel uses one of the following functions:

open_in;;

- : string -> in_channel = <fun>

open_out;;

- : string -> out_channel = <fun>

open_in opens the file if it exists2, and otherwise raises the exceptionSys_error. open_out creates the specified file if it does not exist or truncates it if it does.

let ic = open_in "koala";;

val ic : in_channel = <abstr>

let oc = open_out "koala";;

val oc : out_channel = <abstr>

The functions for closing channels are:

close_in ;;

- : in_channel -> unit = <fun>

close_out ;;

- : out_channel -> unit = <fun>

Reading and Writing

The most general functions for reading and writing are the following:

input_line ;;

- : in_channel -> string = <fun>

input ;;

- : in_channel -> string -> int -> int -> int = <fun>

output ;;

- : out_channel -> string -> int -> int -> unit = <fun>

read_line ;;

- : unit -> string = <fun>

print_string ;;

- : string -> unit = <fun>

print_newline ;;

- : unit -> unit = <fun>

Other values of simple types can also be read directly or appended. These are the values of types which can be converted into lists of characters.

Local declarations and order of evaluation

We can simulate a sequence of printouts with expressions of the form let x = e 1 in e 2. Knowing that, in general, x is a local variable which can be used in e 2, we know that e 1 is evaluated first and then comes the turn of_e_ 2. If the two expressions are imperative functions whose results are () but which have side effects, then we have executed them in the right order. In particular, since we know the return value of e _1_---the constant () of type _unit_---we get a sequence of printouts by writing the sequence of nested declarations which pattern match on ().

let () = print_string "and one," in

let () = print_string " and two," in
let () = print_string " and three" in
print_string " zero";;
and one, and two, and three zero- : unit = ()

Example: Higher/Lower

The following example concerns the game ``Higher/Lower'' which consists of choosing a number which the user must guess at. The program indicates at each turn whether the chosen number is smaller or bigger than the proposed number.

let rec hilo n =

let () = print_string "type a number: " in
let i = read_int ()
in
if i = n then
let () = print_string "BRAVO" in
let () = print_newline ()
in print_newline ()
else
let () =
if i < n then
let () = print_string "Higher"
in print_newline ()
else
let () = print_string "Lower"
in print_newline ()
in hilo n ;;
val hilo : int -> unit = <fun>

Here is an example session:

hilo 64;;

type a number: 88 Lower type a number: 44 Higher type a number: 64 BRAVO


Previous Contents Next