本文包括以下内容:
作为一门语言,它需要提供与外设交互的方式,在各种语言中都提供了输入输出,Scheme语言也不例外。Scheme语言的输入输出功能,是在C基础上的一种封装。
输入输出中我们常用是读和写,对应读与写,在Scheme中有read和write。
read是读操作,它将 Scheme 对象的外部表示转换为对象本身。
read的标准格式为:(read port)
其中port参数可以省略,此时它使用的默认是current-input-port的返回值。
write是写操作,它的标准格式为:(read obj port)
write过程的作用是向给定端口port输出obj的内容。其中输出内容的反斜线、双引号等会被反斜线转义。write的参数中port参数可以省略,默认情况下使用current-output-port的返回值。
这里的默认值我们可以对应到标准输入和输出。从ZOJ的第一题我们看下read的使用。
如下代码:
ZOJ第一题(zoj1001):
(define (main) (let ((a (read)) (b (read))) (if (not(eof-object? a)) (begin (display (+ a b)) (newline) (main) ) ) ) ) (main) |
题目很简单,就是输入两个数,输出和。这里的难点是对于输入结束的判断,在C语言中scanf函数有一个EOF的判断,而在Scheme语言中,我们通过判断输入的输入的值是否为eof来判断,其对应的判断过程为eof-object?(嗯,问号也是调用过程的组成部分,个人非常喜欢这种表达方式),在判断不为结束时继续递归调用,实现C语言中的while循环。
对于字符的读写操作,我们常用的三个过程如下:
read-char
标准格式: (read-char port)
读取一个字符,并将port指针指向下一个字符。
read-char的参数中port可以省略,默认情况下使用current-input-port的返回值。
write-char
标准格式: (write-char port)
write-char过程的作用是向给定端口port输出的内容。
write-char的参数中port可以省略,默认情况下使用current-output-port的返回值。
peek-char
标准格式: (peek-char port)
获取一个字符,但并不将port指针指向下一个字符
peek-char的参数中port可以省略,默认情况下使用current-input-port的返回值。
以一个示例说明这三个过程的调用,示例实现从指定文件中按字符读取内容,并放到一个列表中。
(define input_port (open-input-file "temp")) (define read-char-with-file (lambda (port) (if (eof-object? (peek-char port)) '() (cons (read-char port) (read-char-with-file port)) ) ) ) (if (input-port? input_port) (begin (display (read-char-with-file input_port)) (close-input-port input_port) ) (begin (display "read file form temp failed") (newline) ) ) |
这段代码写得有些复杂,我们可以通过let关键字和call-with-input-file过程来简化这段代码,如下:
(define output-chars (call-with-input-file "temp" (lambda (p) (let f ((x (read-char p))) (if (eof-object? x) '() (cons x (f (read-char p))) ) ) ) ) ) (display output-chars) (newline) |
call-with-input-file的标准调用格式为:
procedure: (call-with-input-file path procedure)
call-with-input-file过程给指定的文件创建一个port,并将这个port传递给第二个参数指定的过程procedure,当procedure执行完成时,call-with-input-file过程将关闭打开的输入port并返回procedure返回的值。
上面的示例已经提了文件操作,关于文件操作,除了针对输入和输出的打开port和关闭port,判断port是否存在的过程外,我们常用还有判断文件存在,删除文件,Scheme提供的这两个过程来与文件系统交互:file-exists?和delete-file
file-exists?的作用是判断文件是否存在,其调用格式如下:
(file-exists? path)
如果文件存在,返回#t,否则返回#f
delete-file的作用是删除一个文件,其调用格式如下:
(delete-file path)
path是字符串类型,如果所给的文件不存在,则会显示错误:No such file or directory
在使用delete-file之前可以调用file-exists?来判断文件是否存在。
除了上面介绍的一些简单输入输出,Scheme还提供了更强大和灵活的输入输出机制,如对编码的处理,对二进制的处理,对字符串的操作等,具体可以见官方文档或《The Scheme Programming Language, 4th Edition》