2013-10-22 100 views
2

如何重定向OCaml中的标准输出? 我试过Format.set_formatter_out_channel,但它似乎没有工作。当我以后使用printf时,文本仍然打印在屏幕上,并且我创建的文件保持空白。重定向标准输出OCaml

回答

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 
+0

谢谢。我希望能够从标准输出切换到文件,而无需将所有printfs更改为fprintfs。懒,我想(当我可以找到并替换 - 但我做了很多printfs,并不得不给每个函数的参数输出通道...)。 –

+0

@Sheeft将'Printf.printf'改为'Format.printf'代替并享受新的超级大国:-) – lukstafi

+0

如果您愿意,您可以使用实际重定向。我会扩大我的答案。 –