LISP:帮助将输入流(带空格)读入字符列表

时间:2011-03-21 19:05:40

标签: lisp common-lisp

我正在尝试编写一个程序,我需要逐个字符地处理字符串,包括空格。该字符串将由运行程序的用户从标准输入流中提供。

我注意到(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),这是关闭的,但那个额外的时期在那里做什么?

2 个答案:

答案 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)

read-char将返回下一个可用字符,read-line将返回整行输入作为字符串。您可以使用coerce将字符串更改为字符列表,例如

(coerce "foo" 'list) => (#\f #\o #\o)