使用 CL 从终端简单读取

Simple reading from terminal with CL

我是一名学生,对 Common Lisp 还很陌生。到目前为止,我只编写了执行自然语言计算的应用程序,从文本文件语料库中读取。现在我试图了解 IO 与终端在 CL 中的工作方式。为此,我正在尝试编写一个超级简单的应用程序,它接受用户的输入,并将其打印回屏幕。这是我的:

(defun main ()
  (with-open-stream stream *terminal-io* :direction :output)
    (print (read-line stream nil)))

然而,这给了我一个错误,说我需要使用 BREAK ON SIGNALS,我不知道该怎么做。你能帮我理解我的代码有什么问题(以及为什么)吗?提前致谢。

如果您想从 CLI 读取输入,您可以使用 *query-io** 流。

(read *query-io*)

记住 read 使用 lisp reader,这可能是一个优势。如果您想阅读一般文本,您应该改用 read-line

*:我不确定 terminal-ioquery-io 之间的区别以及它们在这种情况下是否可以互换.

我想你可能还想用普通的 lisp 编写 shell 脚本,在这种情况下,你将需要 shebang 行,具体取决于你的 lisp 实现,我通常将 SBCL 与 slimen 一起使用,这里你有一个 table:

http://www.cliki.net/Unix%20shell%20scripting

那我觉得既然你是学生又想学习我建议你看一下asdf和uiop,作为sbcl的扩展导入,看看这篇文章:

Why Lisp is Now an Acceptable Scripting Language

有了这个我写了这个脚本来展示这个示例,为了将来也探索 uiop:run-program ;-),并使用不同的流 standard-inputterminal-io,你还应该看看常见的 lisp 流

#!/usr/bin/sbcl --script

(require :uiop)

;;reading comman line arguments
(dolist (element uiop:*command-line-arguments*)
  (uiop:writeln element)
  (write-line element));; look the different output

;; for printing strings on *standard-output*
(write-line "Hi this is a sample script")
(format t "~A ~A ~A ~B ~%" "what you want even a number like" 2 "in binary" 2 )

;; now let's read other arguments
(write-line "please write some thing")

(defparameter line (read-line))

(write-line "you write a:")

(format t "~A" (type-of line))
(write-line "and this contents: ")
(write-line line)

;; now lets use *terminal-io*
(write-line "please introduce another thing" *terminal-io*)

(defparameter line (read-line))

(write-line "you write a:")

(format *terminal-io* "~A" (type-of line))
(write-line "and this contents: ")
(write-line line *terminal-io*)

当我执行它时:

╭─anquegi@toshiba-debian  ~/learn/lisp/Whosebug ‹ruby-2.2.1@laguna› 
╰─$ ./fromterminal.lisp a b c                                                                                                                   148 ↵
"a"
a
"b"
b
"c"
c
Hi this is a sample script
what you want even a number like 2 in binary 10 
please write some thing
calimero
you write a:
(SIMPLE-ARRAY CHARACTER (8))and this contents: 
calimero
please introduce another thing
pato
you write a:
(SIMPLE-ARRAY CHARACTER (4))and this contents: 
pato

还有更多将 common lisp 用作 shell 脚本的示例,如下所示:

learn common lisp with shell scripts,但我建议你探索和学习sbcl、asdf和uiop,祝你好运

简单来说:

  • 您使用 read-line 和朋友从标准输入读取,通常没有额外的参数。因此,(read-line) returns 来自标准输入的一行。当心read,这是一个安全漏洞。

  • 您使用 write-line 和没有其他参数的朋友以及 (format t ...).

  • 写入标准输出
  • 当您想在用户和程序之间建立对话时,您不使用标准输入和输出,而是 *query-io* 将其作为可选参数提供给 read-linewrite-line 等。注意输出可以被缓冲,因此在可移植代码中,您应该执行 (finish-output *query-io*)(force-output *query-io*) 以在预期的用户输入之前刷新输出。