【问题标题】:Reading formatted input test cases from stdin :: OCaml从标准输入读取格式化输入测试用例 :: OCaml
【发布时间】:2019-01-07 22:14:45
【问题描述】:

我尝试按照 glennsl 的建议最小化代码。事实证明,我不知道如何从 OCaml 中读取多行的输入。

例如,假装stdin包含以下模式

5
1 2 3 4 5
3
6 7 8

我需要阅读并打印到stdout。我使用"%d %d %d %d %d\n" 格式说明符就好像我提前知道输入的数量是5,只是为了说明我的问题。

现在下面的代码失败并出现同样的错误Fatal error: exception End_of_file(我试图用更少的代码行重现同样的问题)如果我取消底部部分的注释

let number_of_inputs1 = read_int () in 
let input_arr1 = Scanf.scanf "%d %d %d %d %d\n" (fun a b c d e -> [a]@[b]@[c]@[d]@[e]) in 
let rec print_test_case inputs = 
        match inputs with
        |[] ->(print_newline ();print_string "done test case"; print_newline ();)
        |hd::tl -> (print_int hd; print_string " "; print_test_case tl)
    in print_int number_of_inputs1; print_newline (); print_test_case input_arr1;

(*
let number_of_inputs2 = read_int () in
let input_arr2 = Scanf.scanf "%d %d %d\n" (fun a b c -> [a]@[b]@[c]) in 
print_int number_of_inputs2; print_newline (); print_test_case input_arr2;
*)

它现在打印以下内容,

5
1 2 3 4 5 
done test case

我需要打印类似的东西

5
1 2 3 4 5 
done test case
3
6 7 8
done test case

我应该如何从stdin 正确读取多行格式的输入?

我最初遇到的问题如下。

我有一个问题,在输入的第一行中指定了测试用例的数量tt 测试用例如下。每个测试用例由两行组成

第 1 行:n 的输入数,用于此特定测试用例

第 2 行:n 输入数字用空格分隔

我需要为每个测试用例做一些计算。假设我只需在每个测试用例输出后将它们打印回控制台并显示“完成测试用例”消息。

例如,如果输入如下,

5
3
1 2 3
3
2 1 3
6
3 2 1 5 4 6
4
1 3 4 2
5
3 4 5 1 2

注意在这个问题中有5 测试用例。例如,第一个测试用例有3 输入1 2 3,第三个有63 2 1 5 4 6

我需要打印

1 2 3
done test case
2 1 3
done test case
3 2 1 5 4 6
done test case
1 3 4 2
done test case
3 4 5 1 2
done test case

到目前为止,我已经尝试了以下,

let test_cases = read_int () in (*read the number of test cases*)
let rec print_all_test_cases tc = (*define a function that will call the individual test cases*)
    if (tc > 0) (*check if there are more test cases left*)
    then 
    let num_of_inputs = read_int() in (*read the number of inputs*)
    let rec read_inputs_for_test_case n arr = (*function to recursively read all inputs for the test case*)
        if (n == 0) 
        then arr (*if everthing is read return the accumulated array*)
        else 
        let i = Scanf.scanf "%d " (fun i -> i) in (*else read the input*)
        read_inputs_for_test_case (n-1) (arr @ [i]) (*recurse for the remaining inputs, accumulating current input to the argument*)
    in
    let rec print_test_case inputs = (*print inputs for the test case*)
        match inputs with
        |[] ->(print_newline ();print_string "done test case"; print_newline ();)
        |hd::tl -> (print_int hd; print_string " "; print_test_case tl)
    in 
    print_test_case (read_inputs_for_test_case num_of_inputs []); (*call to read and print inputs*)
    print_all_test_cases (tc-1) (*recursively do the remaining test cases*)
    else () 
in print_all_test_cases test_cases 

它将以下内容打印到stdout

1 2 3 
done test case

并在stderr 上出现以下错误

Fatal error: exception End_of_file

如何正确读取所有内容并按要求打印?

【问题讨论】:

  • 请发送minimal reproducible example 并阅读How to Ask。不要只用任务和错误的描述转储所有代码。表现出一些努力,并将问题减少到可能对其他人有用的事情上,而不仅仅是对自己有用。
  • @glennsl 感谢您的评论。我写了一个较短的版本,但我仍然面临这个问题。如果我可以使用较短版本的解决方案,我将删除原始代码。

标签: ocaml scanf stdout stdin


【解决方案1】:

您的简化代码提取没有错误,如果标准输入有正确的数据,取消注释第二部分应该可以工作。

您可能应该首先使用固定的字符串数据测试您的代码:

let text = "5
1 2 3 4 5
3
6 7 8
"

let source = Scanf.Scanning.from_string text
let number_of_inputs1 = Scanf.bscanf source "%d\n" (fun n -> n)
let input_arr1 =
  Scanf.bscanf source  "%d %d %d %d %d\n" (fun a b c d e -> [a;b;c;d;e])

【讨论】:

    猜你喜欢
    • 2021-06-30
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 2012-02-17
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    相关资源
    最近更新 更多