3

I am trying to open a file which resides in the same folder as the .lsp file I am running, but it gives me this error: Error: No such file or directory : "a.txt"

Here is the code I use:

(defun readfile ()
 (let (lines columns matrix)
  (with-open-file (file "a.txt")
   (setq lines (parse-integer (read-char file)))
   (setq columns (parse-integer (read-char file))))))

Why isn't the file found?

4

1 回答 1

10

它没有找到,因为你没有说文件在哪里。您提供的只是名称/类型,没有目录。

这个函数的文件在哪里并不重要。它不设置路径名的上下文。

通常情况下,Clozure CL 之类的东西会在启动它的目录中查找。

此外,Common Lisp 有一个变量*default-pathname-defaults*. 您可以在那里设置或绑定路径名的默认值。

您对 CCL 的选择:

  • 在正确的目录中启动 CCL
  • 使用 . 在 REPL 中设置当前目录(:cd "/mydir/foo/bar/")。这是特定于 CCL
  • 设置或绑定*default-pathname-defaults*

您还可以根据正在加载的源文件计算路径名。你需要在文件中这样的东西:

(defvar *my-path* *load-pathname*)

(let ((*default-pathname-defaults* (or *my-path*
                                       (error "I have no idea where I am"))))
  (readfile))

顺便说一句:通常 Lisp 侦听器不仅包含“REPL”(Read Eval Print Loop),还支持“命令”。CCL就是这样一个例子。要查看 CCL 提供的命令,请使用:help. 在调试器中还有不同/更多的命令。

Clozure CL 提供的命令查找或设置当前目录非常有用。其他 CL 实现提供了类似的功能 - 但方式不同,因为命令机制(除了 CLIM)和默认命令没有标准。

在 Mac 上的 IDE 中运行的 Clozure Common Lisp 示例:

? :help
The following toplevel commands are available:
 :KAP   Release (but don't reestablish) *LISTENER-AUTORELEASE-POOL*
 :SAP   Log information about current thread's autorelease-pool(s)
        to C's standard error stream
 :RAP   Release and reestablish *LISTENER-AUTORELEASE-POOL*
 :?     help
 :PWD   Print the pathame of the current directory
 (:CD DIR)  Change to directory DIR (e.g., #p"ccl:" or "/some/dir")
 (:PROC &OPTIONAL P)  Show information about specified process <p>
                      / all processes
 (:KILL P)  Kill process whose name or ID matches <p>
 (:Y &OPTIONAL P)  Yield control of terminal-input to process
whose name or ID matches <p>, or to any process if <p> is null
Any other form is evaluated and its results are printed out.
于 2013-05-28T15:50:55.967 回答