LISP - I/O

  • 简述

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

    下表提供了 LISP 最常用的输入函数 -
    序号 功能说明
    1
    read& optional input-stream eof-error-p eof-value recursive-p
    它从输入流中读取 Lisp 对象的打印表示,构建相应的 Lisp 对象,然后返回该对象。
    2
    read-preserving-whitespace& 可选的流内 eof-error-p eof-value 递归-p
    它用于某些需要准确确定终止扩展令牌的字符的特殊情况。
    3
    read-line& optional input-stream eof-error-p eof-value recursive-p
    它读取以换行符结尾的一行文本。
    4
    read-char& optional input-stream eof-error-p eof-value recursive-p
    它从输入流中获取一个字符并将其作为字符对象返回。
    5
    unread-char 字符和可选输入流
    它将最近从输入流中读取的字符放在输入流的前面。
    6
    peek-char& optional peek-type input-stream eof-error-p eof-value recursive-p
    它返回下一个要从输入流中读取的字符,而不实际将其从输入流中删除。
    7
    listen& 可选的输入流
    谓词listen如果输入流中有立即可用的字符,则为真,否则为假。
    8
    read-char-no-hang& optional input-stream eof-error-p eof-value recursive-p
    它类似于read-char,但如果没有得到一个字符,它不会等待一个字符,而是立即返回 nil。
    9
    clear-input& 可选的输入流
    它清除与输入流关联的任何缓冲输入。
    10
    read-from-string string & optional eof-error-p eof-value & key :start :end :preserve-whitespace
    它依次获取字符串的字符并构建一个 LISP 对象并返回该对象。它还返回未读取的字符串中第一个字符的索引,或字符串的长度(或,长度 +1),视情况而定。
    11
    parse-integer 字符串 & 键 :start :end :radix :junk-allowed
    它检查由 :start 和 :end 分隔的字符串的子字符串(默认为字符串的开头和结尾)。它跳过空白字符,然后尝试解析一个整数。
    12
    read-byte 二进制输入流和可选的eof-error-p eof-value
    它从二进制输入流中读取一个字节并以整数形式返回。
  • 从键盘读取输入

    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 JC2182!")
       (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 中的所有输出函数都有一个称为输出流的可选参数,输出被发送到这里。如果未提及或为nil,则输出流默认为变量 *standard-output* 的值。
    下表提供了 LISP 最常用的输出函数 -
    序号 功能及说明
    1
    write 对象和键:流:转义:radix:base:circle:漂亮:level:length:case:gensym:array
    write 对象和键:stream:escape:radix:base:circle:pretty:level:length:case:gensym:array:readably:right-margin:miser-width:lines:pprint-dispatch
    两者都将对象写入由 :stream 指定的输出流,默认为 *standard-output* 的值。其他值默认为用于打印的相应全局变量集。
    2
    prin1 对象和可选的输出流
    print 对象和可选的输出流
    pprint 对象和可选的输出流
    princ 对象和可选的输出流
    所有这些函数都将 object 的打印表示输出到output-stream。但是,存在以下差异 -
    • prin1 返回对象作为它的值。
    • print 使用前面的换行符和后面的空格打印对象。它返回对象。
    • pprint 与 print 类似,只是省略了尾随空格。
    • princ 与 prin1 类似,只是输出没有转义字符
    3
    write-to-string 对象和键:escape:radix:base:circle:pretty:level:length:case:gensym:array
    write-to-string 对象和键:escape:radix:base:circle:pretty:level:length:case:gensym:array:readably:right-margin:miser-width:lines:pprint-dispatch
    prin1-to-string 目的
    princ-to-string 目的
    对象被有效打印,输出的字符做成字符串返回。
    4
    write-char 字符和可选的输出流
    它将字符输出到输出流,并返回字符。
    5
    write-string 字符串和可选的输出流和键:开始:结束
    它将string的指定子串的字符写入输出流。
    6
    write-line 字符串和可选的输出流和键:开始:结束
    它的工作方式与 write-string 相同,但之后输出一个换行符。
    7
    terpri& 可选的输出流
    它将换行符输出到输出流。
    8
    fresh-line& 可选的输出流
    只有当流不在一行的开头时,它才会输出一个换行符。
    9
    finish-output& 可选的输出流
    force-output& 可选的输出流
    clear-output& 可选的输出流
    • 功能finish-output尝试确保发送到输出流的所有输出都已到达其目的地,然后才返回 nil。
    • 功能force-output启动任何内部缓冲区的清空,但返回 nil 而不等待完成或确认。
    • 功能clear-output尝试中止正在进行的任何未完成的输出操作,以允许尽可能少的输出继续到目的地。
    10
    write-byte 整数二进制输出流
    它写入一个字节,即整数的值

    例子

    创建一个名为 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
    
    在哪里,
    • 目标是标准输出
    • control-string 保存要输出的字符和打印指令。
    Aformat directive由波浪号 (~)、以逗号分隔的可选前缀参数、可选的冒号 (:) 和 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