I am trying to have an exact match using Scanf.sscanf below, i,e. I want f to only execute when i match "hello" exactly. But it doesn’t seem to work. Any ideas?
let print_hello i =
let f = Printf.printf "hello\n" in
Scanf.sscanf i "hello" f
;;
utop # print_hello "hello";;
hello
- : unit = ()
utop # print_hello "hello_world";;
hello
- : unit = ()
utop # print_hello "world";;
hello
Exception:
Stdlib.Scanf.Scan_failure
"scanf: bad input at char number 0: looking for 'h', found 'w'".
Is there a way to specify sscanf to have an exact match?
f isn’t a function; it has type unit. So when you call print_hello, it first unconditionally evaluates Printf.printf "hello\n" - which is what’s causing the printing - and then binds the unit result to f.
I’m not very familiar with Scanf.sscanf, but playing around with it a bit I think it does have the behavior you want. E.g.:
# let f s = Scanf.sscanf s "hello\n" ();;
val f : string -> unit = <fun>
# f "hello\n";;
- : unit = ()
# f "hello";;
Exception: End_of_file.
Indeed, I actually just wanted the %! part which I discovered after re-reading the Scanf manual again. So the complete version is below,
# let print_hello i =
Scanf.sscanf i "hello%!" (fun () -> Printf.printf "hello\n")
;;
val print_hello : string -> unit -> unit = <fun>
# print_hello "hello" ();;
hello
- : unit = ()
# print_hello "he" ();;
Exception: End_of_file.
# print_hello "hello world" ();;
Exception:
Stdlib.Scanf.Scan_failure
"scanf: bad input at char number 5: end of input not found".