【问题标题】:Print output into a file or not print output?将输出打印到文件中或不打印输出?
【发布时间】:2011-12-19 22:47:58
【问题描述】:

当我在 lisp 中执行特定函数时,我想保存或忽略输出。我使用 Emacs 和 CCL。例如,

(defun foo (x) (format t "x = ~s~%" x))

如果我执行该函数,它会打印出“x = 5”。但是我不想在缓冲区中打印输出,因为如果我有大量的迭代,模拟的速度会降低。

有什么想法吗?

【问题讨论】:

  • 问题不清楚,(format t ...) 看起来无效,是 elisp 还是 Clojure 还是...?
  • (format t ...) 是 Common Lisp,而不是 elisp。我认为这与 Emacs 没有任何关系。

标签: lisp common-lisp


【解决方案1】:

您可以通过将*standard-output* 绑定到流来临时重定向标准输出。例如,没有输出流的broadcast stream 将作为输出黑洞:

(let ((*standard-output* (make-broadcast-stream)))
  (foo 10)
  (foo 20))
;; Does not output anything.

您也可以使用其他绑定结构来执行此操作,例如 with-output-to-stringwith-open-file

(with-output-to-string (*standard-output*)
  (foo 10)
  (foo 20))
;; Does not print anything;
;; returns the output as a string instead.

(with-open-file (*standard-output* "/tmp/foo.txt" :direction :output)
  (foo 10)
  (foo 20))
;; Does not print anything;
;; writes the output to /tmp/foo.txt instead.

【讨论】:

    【解决方案2】:

    您可以将t 作为format 的第一个参数,而不是format,而是为其提供一个输出文件流,并且该语句的输出将被发送到该文件流。

    但是过多的磁盘 I/O 也会增加运行时间,因此您可以考虑为您的程序设置两种模式,例如调试模式和发布模式,其中调试模式会打印所有诊断消息,而发布模式不会打印任何东西。

    【讨论】:

    • 感谢您的 cmets。但我真正想要的是,像 C 程序一样,您可以运行像 foo > a.txt 这样的程序,如果是这样,输出将打印在 a.txt 文件中。我想知道有没有办法在 lisp 中做到这一点。
    • 编译代码后,您仍然可以使用a.txt 重定向可执行文件的标准输出。另一种方法是调用解释器,如 clisp >a.txt 。这样所有的 REPL 和你的标准输出都会被重定向到a.txt
    • loudandclear,我不太明白你的评论。能详细解释一下吗?
    • 如果您编译您的代码并创建一个名为myexecutable 的可执行文件,那么您可以通过调用myexecutable >a.txt 将输出重定向到一个文件。如果您不想编译,但想将输出发送到文件,则使用 Matthias Benkard 的解决方案或启动您的解释器(在此示例中为 clisp):clisp >a.txt,包括 REPL 在内的所有内容都将是写给a.txt 如果你不想写包括REPL在内的所有东西,只写format 表达式,那么你可以调用格式为: (format error-output "something") 并调用你的解释器为"剪辑 2>a.txt"
    【解决方案3】:

    我不确定我是否理解您的问题,但format 的第二个参数是stream。如果您将其设置为t,它会打印到标准输出,但您也可以将其设置为打开的文件。

    所以这样的事情可以让你选择输出去哪里:

    ;;output to file:
    (setf *stream* (open "myfile" :direction :output
                                  :if-exists :supersede)
    
    ;;alternative to output to standard output:
    ;;(setf *stream* t)
    
    (defun foo (x) (format *stream* "x = ~s~%" x))
    
    (foo 10)
    (close *stream*) ;; only if output sent to a file
    

    【讨论】:

      最近更新 更多