用 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
.
我正在尝试通过 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
.