Reputation: 33
I would like to know what is the difference between :
let b = read_int();;
and
let scan_int () = Scanf.scanf " %d" (fun x -> x)
?
Moreover why Scanf take a function as an entry ?
Upvotes: 3
Views: 4515
Reputation: 18902
In brief, the Scanf
module provides a way to read multiple inputs from an abstract source of characters. For instance, the following function reads two string inputs separated by an =
character from a string:
let f string = Scanf.sscanf string "%s@=%s" (fun x y -> x, y )
assert (f "x=y" = "x","y")
The function argument gives a generic way to combine together the multiple inputs read by the scanf function into a single ouput.
It is therefore a generalization of the few read
functions provided in Pervasives
that can read only one input by line and only from a Pervasives in_channel
.
Upvotes: 3
Reputation: 6144
read_int ()
reads a whole line, changes that whole line into an integer. The whole line must contain only an integer.
Scanf.scanf " %d" (fun x -> x)
also reads a whole line, ditches the white spaces at the beginning of the line then reads an integer written in decimal notation. If there are characters after that integer, they are left in the buffer.
Here is a table:
| line in stdin | read_int | scanf " %d" |
|---------------|----------|-----------------|
| "1234" | 1234 | 1234 |
| " 1234" | ERROR | 1234 |
| "1234 foo" | ERROR | 1234 (foo left) |
| "0xff" | 255 | 0 (xff left) |
What's left in your buffer will usually hinder your next scanf. I would advise you not to use scanf on an unknown input.
About the identity function being needed, that is because scanf can have very complex format string, which will create complex data. How you want that data returned cannot be guessed. Tuples could be used, but OCaml doesn't support arbitrary flattened product in that specific case. Giving what we call a continuation does the job nicely and efficiently.
Upvotes: 12
Reputation: 10148
The main difference is that, as mentioned in the manual, read_int
reads a whole line and expects that the entire line (except the final \n
of course) consists in the integer, whereas with your definition of scan_int
, you can have some non-digits characters after the integer.
The function argument of Scanf.scanf
lets you perform an arbitrary transformation over the input(s).
Upvotes: 3