I'm writing a Brainf*** interpreter in Clojure. I want to pass a program in using stdin. However, I still need to read from stdin later for user input.
Currently, I'm doing this:
$ cat sample_programs/hello_world.bf | lein trampoline run
My Clojure code is only reading the first line though, using read-line
:
(defn -main
"Read a BF program from stdin and evaluate it."
[]
;; FIXME: only reads the first line from stdin
(eval-program (read-line)))
How can I read all the lines in the file I've piped in? *in*
seems to be an instance of java.io.Reader
, but that only provides .read
(one char), .readLine
(one line) and read(char[] cbuf, int off, int len)
(seems very low level).
It's simple enough to read all input data as a single string:
(defn -main []
(let [in (slurp *in*)]
(println in)))
This works fine if your file can fit in available memory; for reading large files lazily, see this answer.
you could get a lazy seq of lines from *in*
like this:
(take-while identity (repeatedly #(.readLine *in*)))
or this:
(line-seq (java.io.BufferedReader. *in*))
which are functionally identical.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With