输入/输出
Table of Contents
通过前面章节的学习,已经可以在 Scheme 的交互式前端中编写并执行程序了。在本章中,将介绍如何 输入 和 输出
使用输入输出,可以从文件中读取数据或向文件中写入数据
从文件输入
open-input-file,read-char 和 eof-object?
- (open-input-file filename) : 打开 一个 文件
- 返回一个 用于输入 的 端口
- (read-char port) :从 端口 中 读取 一个 字符
- 当读取到 文件结尾 ( EOF )时,此函数返回 eof-object
- eof-object? :检查是否已经到文件结尾
- (close-input-port port) : 关闭 输入 端口
下面展示了以字符串形式返回了文件内容:
(define (read-file file-name) (let ((p (open-input-file file-name))) (let loop((ls1 '()) (c (read-char p))) (if (eof-object? c) (begin (close-input-port p) (list->string (reverse ls1))) (loop (cons c ls1) (read-char p))))))
hello.txt文件的内容如下: Hello world! Scheme is an elegant programming language.
测试读取 "hello.txt"文件:
(read-file "hello.txt") ;; "Hello world!\r\nScheme is an elegant programming language.\r\n"
发现 '\r\n' 这样的字符也被打印出来。也可使用 display 函数做 格式化输出 :
(display (read-file "hello.txt")) ;; Hello world! ;; Scheme is an elegant programming language.
call-with-input-file 和 with-input-from-file
上面的代码并没有处理输入错误!!! 下面的函数或语法打开文件的同时并处理错误
(call-with-input-file filename procedure) :
- 将名为 filename 的文件 打开 以供读取输入
- 函数 procedure 接受一个 输入端口 作为参数
- 文件有可能再次使用,因此当 procedure 结束时 文件不会自动关闭
- 文件应该 显式地关闭
(define (read-file file-name) (call-with-input-file file-name (lambda (p) (let loop((ls1 '()) (c (read-char p))) (if (eof-object? c) (begin (close-input-port p) (list->string (reverse ls1))) (loop (cons c ls1) (read-char p))))))) (display (read-file "hello.txt")) ;; Hello world! ;; Scheme is an elegant programming language.
(with-input-from-file filename procedure) :
- 将名为 filename 的文件 打开 以供读取输入
- 函数 procedure 没有任何参数
- 当 procedure 结束时 文件自动关闭
(define (read-file file-name) (with-input-from-file file-name (lambda () (let loop((ls1 '()) (c (read-char))) (if (eof-object? c) (list->string (reverse ls1)) (loop (cons c ls1) (read-char))))))) (display (read-file "hello.txt")) ;; Hello world! ;; Scheme is an elegant programming language.
read
(read port) : 从端口 port 中 读入 一个 S-表达式
用它来读诸如“paren.txt”中带括号的内容就很方便 '(Hello world! Scheme is an elegant programming language.) '(Lisp is a programming language ready to evolve.)
(define (s-read file-name) (with-input-from-file file-name (lambda () (let loop ((ls1 '()) (s (read))) (if (eof-object? s) (reverse ls1) (loop (cons s ls1) (read))))))) (s-read "paren.txt") ; => ('(Hello world! Scheme is an elegant programming language.) ;; '(Lisp is a programming language ready to evolve.))
输出到文件
打开一个用于输出的port
输出有和输入类似的函数,比如:
- (open-output-file filename) : 打开 一个 文件 用作输出,返回该 输出端口
- (close-output-port port) : 关闭 用于输出的 端口
- (call-with-output-file filename procedure) :
- 打开文件 filename 用于输出
- 调用 过程 procedure
- 该函数以 输出端口 为参数
- 不会自动关闭 输出文件
- (with-output-to-file filename procedure) :
- 打开文件 filename 作为 标准输出
- 并调用过程 procedure
- 该过程 没有参数
- 过程 procedure 中返回时,文件被 自动关闭
输出的函数
下面的函数可用于输出。如果参数 port 被 省略 的话,则输出至 标准输出 :
- (write obj port) : 将 obj 输出至 port
- 字符串 被 双引号 括起
- 字符 具有前缀 #\
- (display obj port) : 将 obj 输出至 port
- 字符串 不 被 双引号 括起
- 字符 不 具有前缀 #\
- (newline port) : 开始 新行
- (write-char char port) :向 port 写入 一个 字符