指定在lisp中返回哪个值

时间:2011-12-06 19:31:23

标签: parsing io lisp

我对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)

打印字符在那里,因为我不太擅长理解调试器,想看看我正在阅读的字符。

2 个答案:

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

编辑:用一个不使用自己的行缓冲的函数替换了我自己的函数,因为这里很脆弱,太复杂,而且没必要。另外,添加了对扩展问题的答案。