用 Common Lisp 中的文件输入填充数组

Filling an array with inputs from a file in Common Lisp

我正在尝试通过 lisp 中的 char 将数据从文件获取到数组 char,但我对 common lisp 还很陌生,所以我在途中迷路了。到目前为止,这是我尝试过的方法,但出现了很多错误:

(defun gppinterpreter (filename)

  (defvar *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)
)

这不是一个糟糕的开始。让我们一一来看错误。

当你做一个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,但是有一个方便的 shorthand 来递增一个位置,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)))

此版本至少 运行s 没有错误并生成一个字符向量。您可以将循环替换为对 read-sequence 的单个调用,而不是打印,您很可能只想 return 新向量:

(defun gppinterpreter (filename)
  (let ((my-array (make-array '(10))))
    (with-open-file (stream filename)
      (read-sequence my-array stream))   ; <-
    my-array))                           ; <-

接下来的步骤取决于您的文件的实际结构。您可能想要获取字符串而不是一般向量。您可能想要阅读 文本,其中包含 read-line.