简体   繁体   中英

Reading Delimited Input in Lisp

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?).

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM