2

OCaml で標準出力をリダイレクトするにはどうすればよいですか? 試してみFormat.set_formatter_out_channelましたが、うまくいかないようです。後で printf を使用すると、テキストが画面に表示されたままになり、作成したファイルは空のままになります。

4

1 に答える 1

11

実験が失敗した理由は、Printf.printf が Format モジュールの出力チャネルを使用していないためです。Format モジュールはかなり手の込んだ作業である整形印刷用です。Printf.printf 関数は、フォーマットされたデータを標準出力 (C スタイルの printf) に書き込みます。

本当に標準出力をリダイレクトしたいですか、それとも特定のチャネルに書き込みたいだけですか? oc使用できるチャネルに書き込むには

Printf.fprintf oc ...

それよりも

Printf.printf ...

リダイレクトを行うことは別のことです。でできますUnix.dup2。これを行う方法を示すセッションの例を次に示します。

$ cat redirected
cat: redirected: No such file or directory

$ cat redir.ml
let main () =
    let newstdout = open_out "redirected" in
    Unix.dup2 (Unix.descr_of_out_channel newstdout) Unix.stdout;
    Printf.printf "line of text\n";
    Printf.printf "second line of text\n"

let () = main ()

$ ocamlopt -o redir unix.cmxa redir.ml
$ ./redir

$ cat redirected
line of text
second line of text

これは OCaml I/O システムの背後で低レベルのファイル記述子を変更しているため、少し注意が必要です。簡単なハックとしては素晴らしいです - 私は何度もそれをやった.

アップデート

標準出力を一時的にリダイレクトし、それを元の場所に戻す上記のコードのバージョンを次に示します。

$ cat redirected
cat: redirected: No such file or directory
$
$ cat redir.ml
let main () =
    let oldstdout = Unix.dup Unix.stdout in
    let newstdout = open_out "redirected" in
    Unix.dup2 (Unix.descr_of_out_channel newstdout) Unix.stdout;
    Printf.printf "line of text\n";
    Printf.printf "second line of text\n";
    flush stdout;
    Unix.dup2 oldstdout Unix.stdout;
    Printf.printf "third line of text\n";
    Printf.printf "fourth line of text\n"

let () = main ()
$
$ ocamlopt -o redir unix.cmxa redir.ml
$ ./redir
third line of text
fourth line of text
$
$ cat redirected
line of text
second line of text
于 2013-10-22T20:47:37.750 に答える