2010-01-09 39 views
28

我正在编写我的第一个clojure程序,并且想要读取stdin中的行。如何在clojure中读取stdin(* in *)中的行

当我试试这个:

(doall (map #(println %) (line-seq *in*))) 

我得到这个异常:

Exception in thread "main" java.lang.ClassCastException: clojure.lang.LineNumberingPushbackReader cannot be cast to java.io.BufferedReader (test.clj:0) 

我得到了1.0版本相同的结果和1.1

那么,如何转换*in*成我可以迭代seq?我本来以为,这是很常见的是*in*本身就是迭代,但是,这并不工作,要么 - 如果我尝试使用它直接获取:

java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.LineNumberingPushbackReader (NO_SOURCE_FILE:0) 

此外,是否有做普通文件的任何实例处理clojure?

+2

更换(图#(的println%)(线-SEQ ..))只是(地图println(line-seq ..))可能会很好 – GabiMe

回答

25

尝试在java.io.BufferedReader中包装*in*。 ,还可以使用doseq代替doall,作为devstopfix指出:

(doseq [ln (line-seq (java.io.BufferedReader. *in*))] 
    (println ln)) 

注意line-seq被记录到需要BufferedReader作为其源。

+0

谢谢,它修复了它。 –

+2

此代码不起作用。我得到的错误“doseq需要一个向量来绑定”尝试是@devstopfix写道。它为我工作。 – Jason

+1

@Jason在此表单中使用dorun而不是doseq。 doseq需要一个绑定形式。多伦迫使一个懒惰的seq。 – user1009908

19

你应该使用doseq代替doall

(doseq [line (line-seq (java.io.BufferedReader. *in*))] 
    (println line)) 

doall

遍历序列的连续的nextS,保留了头,并返回它,从而导致整个以次来一次存储在内存中。

doseq

不保留序列的头部。返回nil。

17

只需要注意,对于任何想要只读一行的人,都有read-line函数。

0

对于合理的小投入,以下也将工作:

(let [input-string (slurp *in*)] 
    (println input-string)) 

或者,通过线分割:

(let [lines (clojure.string/split-lines (slurp *in*))] 
    (println lines))