这不是一个糟糕的开始。让我们一一看看错误。
当您执行defvar 时,它定义了一个全局变量(更准确地说,具有全局词法范围,动态范围)。当您在函数体内执行此操作时,每次运行函数时都会发生这种情况。这不是你想要的。你想要一个只有局部词法范围的变量。为此使用let:
(defun gppinterpreter (filename)
(let ((count 0)) ; <-
(setf my-array (make-array '(10)))
(with-open-file (stream filename)
(do ((char (read-char stream nil)
(read-char stream nil)))
((null char))
(setf (aref my-array count) char)
(set count (+ count 1))))
(print my-array)))
当您setf 一个不存在的变量时,它会在全局词法范围内创建,但它的某些行为未指定。不要那样做。你又想要一个局部变量。使用let:
(defun gppinterpreter (filename)
(let ((count 0)
(my-array (make-array '(10)))) ; <-
(with-open-file (stream filename)
(do ((char (read-char stream nil)
(read-char stream nil)))
((null char))
(setf (aref my-array count) char)
(set count (+ count 1))))
(print my-array)))
Set 不是setf。我暂时将细节放在一边; set 几乎从来都不是你想要的。你可以在那里使用setf,但是有一个方便的简写来增加一个地方,incf:
(defun gppinterpreter (filename)
(let ((count 0)
(my-array (make-array '(10))))
(with-open-file (stream filename)
(do ((char (read-char stream nil)
(read-char stream nil)))
((null char))
(setf (aref my-array count) char)
(incf count))) ; <-
(print my-array)))
这个版本至少运行没有错误并产生一个字符向量。您可以用对read-sequence 的一次调用来替换循环,而不是打印,您很可能只想返回新向量:
(defun gppinterpreter (filename)
(let ((my-array (make-array '(10))))
(with-open-file (stream filename)
(read-sequence my-array stream)) ; <-
my-array)) ; <-
接下来的步骤取决于您的文件的实际结构。您可能想要获取字符串而不是一般向量。您可能想用read-line 阅读一行 文本。