let separate = fun formula ->
let rec aux = fun counter begin size ->
match formula.[begin + size] with
| '(' -> aux (counter + 1) begin (size + 1)
| ')' -> if (counter - 1) = 0 then ((String.sub formula (begin + 1) size), (String.sub formula (size + begin + 3) ((String.length formula) - (size + begin + 2)))) else aux (counter - 1) begin (size +1)
| _ -> aux counter begin (size + 1)
in aux 0 (String.index formula '(') 0
;;
let main s=
print_string (fst (separate s))
;;
main "&(A)(B)"
大家好。我的问题是,当我执行这个包含将字符串分成两个的ocaml代码时,我有这个异常:invalid_argument" String.sub / Bytes.sub"。 我想知道,你们能帮助我吗?
答案 0 :(得分:2)
另一个答案和顶部的第一条评论都指出了一个误用的begin
关键字。这是一个小修复,但没有解决安东尼奥的问题。
对于初学者,我不熟悉您使用函数的上下文,我只是想告诉您程序在基于跟踪的方法中出错了。
首先,我对您的代码进行了一些更改,以便它更具可读性,并且更容易找出出现问题的堆栈框架:
let separate = fun formula ->
let rec aux = fun counter start_position size ->
match formula.[start_position + size] with
| '(' -> aux (counter + 1) start_position (size + 1)
| ')' -> if (counter - 1) = 0 then (
(Printf.printf "%d %d %d\n" counter start_position size);
(
((Printf.printf "pass1\n"); (String.sub formula (start_position + 1) size))
,
(String.sub formula (size + start_position + 3) ((String.length formula) - (size + start_position + 2)))
)
)
else aux (counter - 1) start_position (size +1)
| _ -> aux counter start_position (size + 1)
in aux 0 (String.index formula '(') 0
;;
separate "&(A)(B)";;
(*
1 1 2
Exception: Invalid_argument "String.sub / Bytes.sub".
Raised at file "pervasives.ml", line 33, characters 25-45
Called from file "string.ml", line 47, characters 2-23
Called from file "//toplevel//", line 10, characters 4-108
Called from file "toplevel/toploop.ml", line 180, characters 17-56
*)
运行此命令,您将发现触发无效参数异常的调用是aux 1 1 2
的调用。
然后你可以使用这些代码来测试它出错的原因:
let (counter, start_position, size) = (1,1,2) in
let formula = "&(A)(B)" in
(
(size + start_position + 3)
,
(String.length formula) - (size + start_position + 2)
) ;;
(*
- : int * int = (6, 2)
*)
这就是你知道为什么String.sub
不接受你的论点的原因:
String.sub "&(A)(B)" 6 2;;
(* Exception: Invalid_argument "String.sub / Bytes.sub".
Called from file "toplevel/toploop.ml", line 180, characters 17-56 *)
这是我可以帮助你的。在OCaml中进行调试需要时间,但这是可行的。回到好的打印技巧。 我希望这些信息足以让您了解逻辑错误的原因。我希望你能根据你的问题背景找出解决问题的方法。
答案 1 :(得分:0)
您的代码无法编译,因为您使用的是关键字begin
。
修改后:
let separate = fun formula ->
let rec aux = fun counter b size ->
match formula.[b + size] with
| '(' -> aux (counter + 1) b (size + 1)
| ')' -> if (counter - 1) = 0 then ((String.sub formula (b + 1) size), (String.sub formula (size + b + 3) ((String.length formula) - (size + b + 2)))) else aux (counter - 1) b (size +1)
| _ -> aux counter b (size + 1)
in aux 0 (String.index formula '(') 0
;;
现在,要获得有关异常的更多可见性,请添加以下内容:
let () = Printexc.record_backtrace true;;
编译它(使用ocamlbuild)并运行它,你会得到像:
Fatal error: exception Invalid_argument("String.sub / Bytes.sub")
Raised at file "pervasives.ml", line 33, characters 20-45
Called from file "string.ml" (inlined), line 47, characters 2-23
Called from file "sep.ml", line 5, characters 75-153
Called from file "sep.ml" (inlined), line 11, characters 22-34
Called from file "sep.ml", line 15, characters 0-14