chaosink
chaosink

Reputation: 1483

How can I read a string in a line in Common Lisp?

aaa bbb ccc

Fot the above line, I just want to get the sring "aaa", just like scanf("%s",str) in C.

Upvotes: 2

Views: 742

Answers (2)

Mark Karpov
Mark Karpov

Reputation: 7599

To solve your problem gracefully you need a function to extract words. This may work, or you can find some good library:

CL-USER> (defun split (str token &aux result (len (length str)))
           (labels ((rec (i)
                      (if (< i len)
                          (let ((p (or (position token str :start i)
                                       len)))
                            (when (/= p i)
                              (push (subseq str i p) result))
                            (rec (1+ p)))
                          (reverse result))))
             (rec 0)))
SPLIT

This function traverses given string and copies its parts that don't contain given token. Note how we don't copy entire string on every recursive call, but move 'pointer' i to know where to start next search.

Now you can use nth to access any word:

CL-USER> (nth 0 (split "aaa bbb ccc" #\space))
"aaa"
CL-USER> (nth 1 (split "aaa bbb ccc" #\space))
"bbb"
CL-USER> (nth 2 (split "aaa bbb ccc" #\space))
"ccc"

Upvotes: 1

sds
sds

Reputation: 60014

In C, scanf does tokenization, i.e., it splits on whitespace. This corresponds to read in Common Lisp:

(with-input-from-string (s "aaa bbb ccc")
  (list (read s) (read s) (read s)))
==> (AAA BBB CCC)

Note that read returns symbols for unquoted strings; if you want strings, you are looking for something like:

(defparameter *my-string* "aaa bbb ccc")
(subseq *my-string* 0 (position #\Space *my-string*))
==> "aaa"

Upvotes: 1

Related Questions