Search code examples
fileclojuretxt

Clojure - read text file and enter it as a list


I am having trouble with some basic IO operations using Clojure. I have a text file which I need to read, split with the "|" character, and enter into a list for later processing. Here are the contents of my text file:

1|John Smith|123 Here Street|456-4567 
2|Sue Jones|43 Rose Court Street|345-7867 
3|Fan Yuhong|165 Happy Lane|345-4533

And here is my current code:

((defn -main [] 
(println "Enter an option: \n")

(let [choice (read-line)]
  
  (cond (= choice "1") 
        (let [cust-contents (slurp "file.txt")
              nums-as-strings (clojure.string/split cust-contents #"|")
              numbers (map read-string nums-as-strings)]
              (print numbers)
        ) 
  )
) ) )


(-main)

I would think this code to work, however here is the error I get when running my program:

(; Execution error at user/eval7923$-main (REPL:11).
; EOF while reading

Could anyone please guide me on where I went wrong and on how to fix this?


Solution

  • That error is actually caused when you call read-string with argument " ".

    And where that " " comes from? You used the wrong regex in clojure.string/split, you should use #"\|" instead of #"|".

    And even then, you can't call read-string on everything, as it would soon crash again, trying to parse "456-4567".

    Also, ending parentheses belong to the same line.

    If your file contains newlines, you will need clojure.string/split-lines and if you will also implement 2 Display Product Table, 3. Display Sales Table and so on (I know the context for this code), case will be better than cond.

    Here is your code with some improvements:

    (ns homework.core
      (:require [clojure.string :as s])
      (:gen-class))
    
    (defn -main []
      (println "Enter an option: \n")
      (let [choice (read-line)]
        (case choice
              "1" (->> (s/split-lines (slurp "file.txt"))
                       (mapv #(s/split % #"\|"))
                       println)
              "Wrong number")))
    
    (-main)