【问题标题】:Filling an array with inputs from a file in Common Lisp用 Common Lisp 中文件的输入填充数组
【发布时间】:2021-12-28 19:38:39
【问题描述】:

我试图在 lisp 中按字符从文件获取数据到数组 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)
)

【问题讨论】:

  • set 应该是 setqsetf
  • 你应该使用let来声明局部变量。 defvar 通常不在函数内部使用。

标签: arrays common-lisp


【解决方案1】:

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

当您执行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 阅读一行 文本。

【讨论】:

  • 哇,非常感谢。你的回答不仅帮助了我,也让我明白了背后的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
相关资源
最近更新 更多