我对lisp编程完全陌生。我需要为一个从xml doc中读出单词的类编写一个程序。无论如何,我写了这个函数,它接受一个数组(word)和一个文件流(in)。我希望它循环直到它到达流中的#\空格,同时将每个收集的字符添加到单词中。然后我想要回复这个词。我确定我做了很多错事,但这是我的方法。我很确定最后的返回函数完全不合适:
(defun get-string (in word)
(loop for char = (read-char in nil)
while (not (char= char #\space))
do(vector-push-extend char word))
(return word))
现在我有另一个问题。循环在找到空格后继续查找字符,我得到了一堆nils。此外,我需要停止换行,但我不知道如何。我绑了这个,但它只读了每一个角色。
(defun get-string (in word)
(loop for char = (read-char in nil)
while (not (or (char= char #\space)
(char= char #\newline)))
do(print char))
word)
打印字符在那里,因为我不太擅长理解调试器,想看看我正在阅读的字符。
答案 0 :(得分:4)
word
是变量,变量的值是其值。在DEFUN
正文中,返回最后一个表达式的值。因此,如果您想要返回word
的值,则不需要word
周围的返回。
答案 1 :(得分:1)
您不需要明确的return
语句。这仅适用于词汇范围的早期回报。所以这个版本有效:
(defun get-string (in word)
(loop for char = (read-char in nil)
while (not (char= char #\space))
do (vector-push-extend char word))
word)
但是我想知道你的函数中的另一个东西:word参数是否只是为了传递空数组?你不需要传递缓冲区来进行字符串处理,Lisp不是C.感谢自动内存管理,你可以在函数中创建字符串并返回它们。
因此,我会写一个函数来读取像这样的流中空格分隔的单词:
(defun read-word (&optional (stream *standard-input*))
(with-output-to-string (word)
(loop for char = (read-char stream nil)
while (and char
(char/= char #\Space)
(char/= char #\Newline))
do (write-char char word))))
关于你新增加的问题:我不明白你读取空格时你的循环不应该停止的原因。 OTOH,你没有检查的是NIL,即EOF时的返回值。这就是为什么我在我自己的函数char
中添加了第一个条件(只是and
)。