2010-01-09 77 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))