r1si
r1si

Reputation: 1164

String to list without #\ in common lisp

I'd like to turn String into lists. For example, http => (h t t p).

I try:

(defun string-to-list (s)
  (assert (stringp s) (s) "~s :questa non e una stringa")
  (coerce s 'list))

but if I do

(string-to-list "http")

results:

(#\h #\t #\t #\p).

Can I remove #\ ? thanks in advance :)

Upvotes: 8

Views: 7622

Answers (4)

Rainer Joswig
Rainer Joswig

Reputation: 139251

Why would you do that? What you ask is to split a string (a one-dimensional array of characters) into a list of symbols. Do you really want that?

#\h is a character object printed.

You can print them differently:

CL-USER 8 > (princ #\h)
h

CL-USER 9 > (prin1 #\h)
#\h

Let's print the list using PRINC:

CL-USER 10 > (map nil #'princ (coerce "Hello!" 'list))
Hello!

Btw., since strings, vectors and lists are sequences, you can MAP directly over the string...

CL-USER 11 > (map nil #'princ "Hello!")
Hello!

Upvotes: 20

Rainer Joswig
Rainer Joswig

Reputation: 139251

You can print characters unescaped. See the variable *PRINT-ESCAPE*.

The function WRITE has a keyword parameter :ESCAPE for that:

(defun string-to-list (s)
  (assert (stringp s) (s) "~s :questa non e una stringa")
  (write (coerce s 'list) :escape nil)


CL-USER 11 > (string-to-list "abcd")
(a b c d)
(#\a #\b #\c #\d)

In above example the first form is printed by calling WRITE and the second form is the return value printed by the REPL.

Upvotes: 3

Rörd
Rörd

Reputation: 6681

Expanding upon larsmans' answer, you can print lowercase symbols unquoted if you change the readtable:

(let ((*readtable* (copy-readtable)))
  (setf (readtable-case *readtable*) :preserve)
  (prin1 (loop for c in (coerce "http" 'list)
               collecting (intern (string c)))))

This will print (h t t p) and return (|h| |t| |t| |p|).

Upvotes: 3

Fred Foo
Fred Foo

Reputation: 363517

You can turn a string into a symbol with intern. You can turn a character into a string with string. Interning a lower-case string might cause it to be printed as |h| instead of h, so you'll want to string-upcase it. Putting all that together gives:

(loop for c in (coerce "http" 'list)
      collecting (intern (string-upcase (string c))))

Upvotes: 3

Related Questions