标题基本上都说明了一切。我知道通过OCaml的Str模块使用regexp,这个任务非常简单 - 但是,假设您只允许使用标准库和Scanf模块。我有兴趣采用这样的字符串:
"12 34 555 6 23 34 5663 234 ..."
返回一个看起来像这样的数组
[|12; 34; 555; 6; 23; 34; 5663; 234; |]
有人可以帮帮我吗?我发现Scanf文档(可用http://caml.inria.fr/pub/docs/manual-ocaml/libref/Scanf.html)对于理解如何使用模块非常无益
答案 0 :(得分:2)
不确定它是多么惯用,但它有效:
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 []));;
一点点测试:
# parse_integers " 20 3 22";;
- : int array = [|20; 3; 22|]
(更新)
正如评论中所解释的那样,上面的代码不是尾递归的,而下面的代码是:
...
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 ...
答案 1 :(得分:0)
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|]
答案 2 :(得分:-1)
所有Scanf函数的格式字符串指定固定数量的值;因此,您不能期望使用Scanf中的函数从字符串中读取可变数量的值。
如果将字符串分成几部分,则可以使用Scanf.sscanf s "%d" (fun x -> x)
将每个部分转换为int。但是,函数int_of_string
对于此目的来说要简单得多。
我说你应该先把字符串分成几块。