OCaml乘法表函数异常处理问题:输入错误时无法正常结束
OCaml乘法表函数异常处理修复
你的问题出在异常处理的递归逻辑上:当用户输入非数字触发Failure异常时,你调用了mtable x y递归,但之后又返回了product。这会导致新的递归调用完成后,原来的函数栈帧会继续执行后续的判断逻辑——哪怕已经到达乘法表末尾,旧的栈帧还会继续运行,无法正常终止程序。
修改后的代码
let rec mtable x y = Printf.printf " %d * %d = " x y; flush stdout; let product = x * y in let u_input = read_line () in let t_input = String.trim u_input in match t_input with | "q" -> Printf.printf "Good bye\n" | another -> let number = try int_of_string another with | Failure(_) -> Printf.printf "The answer must be a number\n"; mtable x y (* 直接返回递归调用,不再继续执行后续逻辑 *) in if product = number then if x = 10 && y = 10 then Printf.printf "You have reached the end of the table\n" else if y = 10 then mtable (x + 1) 1 else ( Printf.printf "Right answer\n"; mtable x (y + 1) ) else ( Printf.printf "Wrong answer\n"; mtable x y );; mtable 10 8;;
关键修改说明
- 异常分支中直接返回
mtable x y:这样当前函数会立即终止,控制权完全交给新的递归调用,不会再执行后续的答案判断逻辑,避免了旧栈帧残留导致的无法结束问题。 - 调整了判断顺序:先判断答案是否正确,再根据x、y的位置决定下一步,逻辑更清晰,避免了冗余的条件组合。
另外,还可以把输入读取和转换的逻辑抽成辅助函数,让主函数更简洁:
let rec get_valid_number prompt = Printf.printf "%s" prompt; flush stdout; let input = String.trim (read_line ()) in if input = "q" then ( Printf.printf "Good bye\n"; exit 0 ) else try int_of_string input with | Failure(_) -> Printf.printf "The answer must be a number\n"; get_valid_number prompt let rec mtable x y = let product = x * y in let prompt = Printf.sprintf " %d * %d = " x y in let number = get_valid_number prompt in if product = number then if x = 10 && y = 10 then Printf.printf "You have reached the end of the table\n" else if y = 10 then mtable (x + 1) 1 else ( Printf.printf "Right answer\n"; mtable x (y + 1) ) else ( Printf.printf "Wrong answer\n"; mtable x y );; mtable 10 8;;
这个版本把输入验证的逻辑分离出去,主函数只负责乘法表的核心逻辑,可读性更好,同时也处理了输入"q"直接退出的情况。
内容的提问来源于stack exchange,提问作者user324885
相关产品推荐
相关产品推荐

