LISP - 输入与输出



Common LISP 提供了许多输入输出函数。我们已经使用了 format 函数和 print 函数进行输出。在本节中,我们将研究 LISP 提供的一些最常用的输入输出函数。

输入函数

下表提供了 LISP 最常用的输入函数:

序号 函数及描述
1

read & 可选 input-stream eof-error-p eof-value recursive-p

它从 input-stream 读取 Lisp 对象的打印表示形式,构建相应的 Lisp 对象,并返回该对象。

2

read-preserving-whitespace & 可选 in-stream eof-error-p eof-value recursive-p

它用于某些特殊情况,在这些情况下,需要精确确定哪个字符终止了扩展标记。

3

read-line & 可选 input-stream eof-error-p eof-value recursive-p

它读取以换行符结尾的一行文本。

4

read-char & 可选 input-stream eof-error-p eof-value recursive-p

它从 input-stream 获取一个字符,并将其作为字符对象返回。

5

unread-char character & 可选 input-stream

它将最近从 input-stream 读取的字符放回 input-stream 的开头。

6

peek-char & 可选 peek-type input-stream eof-error-p eof-value recursive-p

它返回将要从 input-stream 读取的下一个字符,而不会实际将其从输入流中删除。

7

listen & 可选 input-stream

谓词 listen 如果 input-stream 中有字符立即可用,则为真,否则为假。

8

read-char-no-hang & 可选 input-stream eof-error-p eof-value recursive-p

它类似于 read-char,但如果它没有获取到字符,它不会等待字符,而是立即返回 nil。

9

clear-input & 可选 input-stream

它清除与 input-stream 关联的任何缓冲输入。

10

read-from-string string & 可选 eof-error-p eof-value & 键 :start :end :preserve-whitespace

它依次获取字符串的字符并构建一个 LISP 对象,并返回该对象。它还返回字符串中第一个未读取字符的索引,或者字符串的长度(或长度+1),具体情况视情况而定。

11

parse-integer string & 键 :start :end :radix :junk-allowed

它检查由 :start 和 :end(默认为字符串的开头和结尾)限定的字符串子串。它跳过空格字符,然后尝试解析一个整数。

12

read-byte binary-input-stream & 可选 eof-error-p eof-value

它从 binary-input-stream 读取一个字节,并将其以整数的形式返回。

从键盘读取输入

read 函数用于从键盘获取输入。它可能不带任何参数。

例如,考虑以下代码片段:

(write ( + 15.0 (read)))

假设用户从 STDIN 输入中输入 10.2,它将返回:

25.2

read 函数从输入流中读取字符,并通过解析将其解释为 Lisp 对象的表示形式。

示例

创建一个名为 main.lisp 的新源代码文件,并在其中输入以下代码:

; the function AreaOfCircle
; calculates area of a circle
; when the radius is input from keyboard

(defun AreaOfCircle()
(terpri)
(princ "Enter Radius: ")
(setq radius (read))
(setq area (* 3.1416 radius radius))
(princ "Area: ")
(write area))
(AreaOfCircle)

执行代码时,它将返回以下结果:

Enter Radius: 5 (STDIN Input)
Area: 78.53999

示例

创建一个名为 main.lisp 的新源代码文件,并在其中输入以下代码。

(with-input-from-string (stream "Welcome to Tutorials Point!")
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (peek-char nil stream nil 'the-end))
   (values)
)

执行代码时,它将返回以下结果:

#\W 
#\e 
#\l 
#\c 
#\o 
#\m 
#\e 
#\Space 
#\t 
#\o 
#\Space 

输出函数

LISP 中的所有输出函数都带有一个名为 output-stream 的可选参数,输出将发送到该参数。如果未提及或为 nil,则 output-stream 默认为变量 *standard-output* 的值。

下表提供了 LISP 最常用的输出函数:

序号 函数及描述
1

write object & 键 :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array

write object & 键 :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array :readably :right-margin :miser-width :lines :pprint-dispatch

两者都将对象写入由 :stream 指定的输出流,该流默认为 *standard-output* 的值。其他值默认为为打印设置的相应全局变量。

2

prin1 object & 可选 output-stream

print object & 可选 output-stream

pprint object & 可选 output-stream

princ object & 可选 output-stream

所有这些函数都将对象的打印表示形式输出到 output-stream。但是,存在以下差异:

  • prin1 将对象作为其值返回。

  • print 在对象前面打印一个换行符,并在后面打印一个空格。它返回对象。

  • pprint 与 print 类似,只是省略了尾随空格。

  • princ 与 prin1 类似,只是输出没有转义字符

3

write-to-string object & 键 :escape :radix :base :circle :pretty :level :length :case :gensym :array

write-to-string object & 键 :escape :radix :base :circle :pretty :level :length :case :gensym :array :readably :right-margin :miser-width :lines :pprint-dispatch

prin1-to-string object

princ-to-string object

对象被有效地打印,并且输出字符被制成一个字符串,该字符串被返回。

4

write-char character & 可选 output-stream

它将字符输出到 output-stream,并返回字符。

5

write-string string & 可选 output-stream & 键 :start :end

它将 string 指定子字符串的字符写入 output-stream

6

write-line string & 可选 output-stream & 键 :start :end

它的工作方式与 write-string 相同,但在之后输出一个换行符。

7

terpri & 可选 output-stream

它将换行符输出到 output-stream

8

fresh-line & 可选 output-stream

仅当流不在行的开头时,它才会输出一个换行符。

9

finish-output & 可选 output-stream

force-output & 可选 output-stream

clear-output & 可选 output-stream

  • 函数 finish-output 尝试确保发送到 output-stream 的所有输出都已到达其目的地,然后才返回 nil。

  • 函数 force-output 启动清空任何内部缓冲区,但在等待完成或确认之前返回 nil。

  • 函数 clear-output 尝试中止正在进行的任何未完成的输出操作,以允许尽可能少的输出继续到达目的地。

10

write-byte integer binary-output-stream

它写入一个字节,即 integer 的值。

示例

创建一个名为 main.lisp 的新源代码文件,并在其中输入以下代码。

; this program inputs a numbers and doubles it
(defun DoubleNumber()
   (terpri)
   (princ "Enter Number : ")
   (setq n1 (read))
   (setq doubled (* 2.0 n1))
   (princ "The Number: ")
   (write n1)
   (terpri)
   (princ "The Number Doubled: ")
   (write doubled)
)
(DoubleNumber)

执行代码时,它将返回以下结果:

Enter Number : 3456.78 (STDIN Input)
The Number: 3456.78
The Number Doubled: 6913.56

格式化输出

format 函数用于生成格式良好的文本。它具有以下语法:

format destination control-string &rest arguments

其中,

  • destination 是标准输出
  • control-string 包含要输出的字符和打印指令。

格式指令 由波浪号 (~)、可选的前缀参数(用逗号分隔)、可选的冒号 (:) 和 at 符号 (@) 修饰符以及指示此指令类型的单个字符组成。

前缀参数通常是整数,表示为带可选符号的十进制数字。

下表提供了常用指令的简要说明:

序号 指令及描述
1

~A

后面跟着 ASCII 参数。

2

~S

后面跟着 S 表达式。

3

~D

用于十进制参数。

4

~B

用于二进制参数。

5

~O

用于八进制参数。

6

~X

用于十六进制参数。

7

~C

用于字符参数。

8

~F

用于定点浮点数参数。

9

~E

指数浮点数参数。

10

~$

美元和浮点数参数。

11

~%

打印一个新行。

12

~*

忽略下一个参数。

13

~?

间接寻址。下一个参数必须是字符串,下一个参数必须是列表。

示例

让我们重写计算圆形面积的程序:

创建一个名为 main.lisp 的新源代码文件,并在其中输入以下代码。

(defun AreaOfCircle()
   (terpri)
   (princ "Enter Radius: ")
   (setq radius (read))
   (setq area (* 3.1416 radius radius))
   (format t "Radius: = ~F~% Area = ~F" radius area)
)
(AreaOfCircle)

执行代码时,它将返回以下结果:

Enter Radius: 10.234 (STDIN Input)
Radius: = 10.234
Area = 329.03473
广告