Reputation: 21
The title basically says it all. I am aware that through the use of regexp via OCaml's Str module, this task is quite simple - however, suppose you are only allowed to use the standard library and Scanf module. I am interested in taking a string looks like this:
"12 34 555 6 23 34 5663 234 ..."
And returning an array that looks like this
[|12; 34; 555; 6; 23; 34; 5663; 234; |]
Can someone help me out? I found the Scanf documentation (available http://caml.inria.fr/pub/docs/manual-ocaml/libref/Scanf.html) to be pretty unhelpful in understanding how to use the module
Upvotes: 1
Views: 2689
Reputation: 38809
Not sure how idiomatic it is, but it works:
let parse_integers s =
let stream = (Scanning.from_string s) in
let rec do_parse acc =
try
do_parse (Scanf.bscanf stream " %d " (fun x -> x :: acc))
with
Scan_failure _ -> acc
| End_of_file -> acc
in Array.of_list (List.rev (do_parse []));;
A little test:
# parse_integers " 20 3 22";;
- : int array = [|20; 3; 22|]
(Update)
As explained in comments, the above code is not tail-recursive, whereas the following one is:
...
let rec do_parse acc =
match (Scanf.bscanf stream " %d " (fun x -> x :: acc))
with
| xs -> do_parse xs
| exception Scan_failure _ -> acc
| exception End_of_file -> acc
in ...
Upvotes: 2
Reputation: 1619
let rec f acc s =
if s="" then
Array.of_list (List.rev acc)
else
Scanf.sscanf s "%d %[^\n]" (fun n s-> f (n::acc) s)
;;
f [] "12 34 555 6 23 34 5663 234";;
# - : int array = [|12; 34; 555; 6; 23; 34; 5663; 234|]
Upvotes: 0
Reputation: 66803
The format string for all the Scanf functions specifies a fixed number of values; thus, you can't expect to use a function from Scanf to read a variable number of values from a string.
If you break your string into pieces, you can use Scanf.sscanf s "%d" (fun x -> x)
to translate each piece into an int. However, the function int_of_string
is much simpler for that purpose.
I'd say you should start by breaking the string into pieces.
Upvotes: -1