我正在尝试编写一个程序,我需要逐个字符地处理字符串,包括空格。该字符串将由运行程序的用户从标准输入流中提供。
我注意到(read)
函数只有在捕获了一些非空白字符后才会停止,并切断从第一个空白字符开始的所有内容。
换句话说,如果我执行(read)
功能并输入hi to you
,它将返回HI
。我希望我的函数返回的是(#\h #\i #\Space #\t #\o #\Space #\y #\o #\u)
。任何人都可以给我一些关于如何实现这一点的指示?对不起,伙计们,我对LISP非常陌生,但我很喜欢它。
编辑:我尝试过的一件事是使用(cons)和(read-char)。例如:(cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) (read-char)))))
。当用户输入“你好”时,会输出(#\h #\e #\l #\l . #\o)
,这是关闭的,但那个额外的时期在那里做什么?
答案 0 :(得分:5)
Xach基本上回答了你的主要问题:你可能想要阅读一行read-line
并将其强制列入一个列表:(coerce (read-line) 'list)
然后对此列表执行某些操作。
read
不起作用的原因是它读取并返回s表达式:
> (car (read))
(foo bar baz) ; this is me typing
FOO
所以它只是在输入“hi to you”中读取第一个符号hi
并停止。连续调用read将返回其余部分:
> (list (read) (read) (read))
hi to you ; me typing again
(HI TO YOU)
您可能仍希望使用Xach的建议来获取您的意见。
要解决您的其他问题,该字符列表中有一个点的原因是表达式(cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) (read-char)))))
以(cons (read-char) (read-char))
结尾,其中包含两个字符。
Cons创建“cons cells”或Lisp对,它们表示为虚线对:
> (cons 'a 'b)
(A . B)
Lisp列表通常由nil
形成,或空列表作为最后一个元素。但它们实际上表示为带有这些缺点单元的链表,这些是相同的:
(a . (b . (c . ())))
(a b c)
它们通常只是以第二种方式印刷。在您的情况下,最后一个元素是一个字符,因此它打印为虚线尾部列表。在REPL上进行实验,这是有道理的:
> '(a . (b . c))
(A B . C)
> '(a b . c)
(A B . C)
> '(a b c)
(A B C)
> '(a . (b . (c . nil)))
(A B C)
所以你想用原始表达式做的是:
> (cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) (cons (read-char) nil)))))
(#\h #\e #\l #\l #\o)
答案 1 :(得分:3)