2

In Common Lisp, I need to capture user input in the form of a list of reals. This list is terminated by two zeros in a row. For example, 5.0 0 6.0 3 2.0 5 1.0 7 13.0 8 0 0 should return the list (5.0 0 6.0 3 2.0 5 1.0 7 13.0 8).

I've come across the function read-delimited-list, which takes a single character as an ending point. I can stop at a single zero, but I'm not sure how to expand this function, and I don't know of another function that takes a delimited string instead of a char.

EDIT Thanks to the accepted answer, I've developed the following:

(butlast (loop for y = -1 then x for x = (read stream) until (and (= 0 x) (= 0 y))
    collect x)))

It seems a bit more readable to me (and at this point I'm openly admiting that my Lisp eyes are only 3 days old), and I'm not sure about performance implications (does collect append or reverse the list after the loop exits scope? is there an easier way to chop off the last element, or simply not append it?).

2 Answers 2

4

For such simple case you can just use read in a loop, collect the results read so far and stop, when the last two are zeros.

(defun read-double-zero-terminated-list (stream)
  (do* ((prev -1 val)
        (val (read stream) (read stream))
        list)
       ((and (zerop prev) (zerop val)) (reverse (cdr list)))
     (push val list)))

read-delimited-list is intended for the cases of creating specialized syntax, so it's probably overkill here.

Sign up to request clarification or add additional context in comments.

3 Comments

Not overkilling, just plain wrong. read-delimited-list works at a character level input... I bet efritz doesn't want to stop on a 0.17.
Why are you using do*? It seems to me like it would also work with do loop.
Remember to always set *read-eval* to nil when using read like this, to protect against #..
0

The best way to parse numbers in Common Lisp is to use the library parse-number. If your user input can be read line by line, you can simply split the lines on whitespace and use parse-number on the results.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.