2.1. open-input-fileread-char, and eof-object?

The function (open-input-file filename) is available to open a file. This function return a port for input. The function (read-char port) is to read a character from the port. As this function returns eof-object when it reaches the end of the file (EOF), you can check it by using eof-object?. The function (close-input-port port) is to close the input port. The [code 1] shows a function that returns file contents as string.

[code 1]

(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))))))
为什么要reverse,因为cons c ls1 是把先前读取的放在后面,而c放在前面,为什么不(cons ls1 c)

#\!)
> (define c (cons 1 2))
> (cons c 3)
'((1 . 2) . 3)

> (cons 3 c)
'(3 1 . 2)

把cons放在car位置上,会有一个(),而放在第二个则没有。

For instance, the result shown in [example 1] is obtained by applying the [code 1] to a file [hello.txt]. As the newline character is represented by '\n', it is not easy to read. Function display is available, however, for formatting ([example 2]).

[hello.txt]

Hello world!
Scheme is an elegant programming language.

[example 1]

(cd "C:\\doc")
(read-file "hello.txt")
;Value 14: "Hello world!\nScheme is an elegant programming language.\n"

[example 2]

(display (read-file "hello.txt"))
Hello world!
Scheme is an elegant programming language.
;Unspecified return value

2.2. Syntaxes call-with-input-file and with-input-from-file

You can open a file for input using the syntax call-with-input-file or with-input-from-file. These syntaxes are convenient because they handle errors.

(call-with-input-file filename procedure)
It opens a file named filename for input. The procedure is a function that takes input port as an argument. The file should be closed explicitly because it is not closed when the control is returned from the procedure if the input port is potentially used again. The [code 1] can be rewritten like [code 2] using call-with-input-file.

它打开一个文件来作为输入,接受一个函数(port做为参数)

[code 2]

(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)))))))
(with-input-from-file filename procedure) 自动关闭
It opens a file named filename as the standard input. The procedure is a function with no argument. The file is closed when the control is returned from the procedure. [code 3] shows the rewritten function of [code 1] using with-input-from-file.

[code 3]

(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)))))))

2.3. read

The function (read port) reads a S-expression from the port. It is convenient to read contents with parentheses like [paren.txt]. (这个真是为lisp专门设计的。

[paren.txt]

'(Hello world!
Scheme is an elegant programming language.) '(Lisp is a programming language ready to evolve.)

[code 4]

(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)))))))

The following shows the result of reading paren.txt by s-read.

(s-read "paren.txt")
⇒ ((quote (hello world! scheme is an elegant programming language.))
(quote (lisp is a programming language ready to evolve.)))
demo1:

'(hello wrodl)
'(you )
'(can)

输出:'('(hello wrodl) '(you) '(can))

demo2:

(you) (can)

'((you) (can))

demo3:
(you (we)) (can)
输出:'((you (we)) (can))

Exercise 1

Write the function read-lines that returns a list of strings which correspond to each line of file contents. The newline character is represented by#\Linefeed in Scheme. Following is the result of applying this function to the hello.txt.

(read-lines "hello.txt") ⇒ ("Hello world!" "Scheme is an elegant programming language.")

3. Output to files

3.1. Making a Port for output

Similar functions to those for input are available to make output ports.

(open-output-file filename)
It opens a file for output and returns a output port.
(close-output-port port)
It closes the port for output.
(call-with-output-file filename procedure)
It opens a file named filename for output and calls procedure. The function procedure takes the port as an argument.
(with-output-to-file filename procedure)
It opens a file named filename as the standard output and calls procedure. The procedure is a function with no argument. The file is closed when the control is returned from the procedure.

3.1. Functions for output

Following functions for output are available. These functions output to the standard output if the port is omitted.

(write obj port)
It outputs the obj to the port. Strings are enclosed in double quotes and characters are combined with the #\.
(display obj port)
It outputs the obj to the port. Strings are not enclosed in double quotes and characters are not combined with the #\.
(newline port)
It begins a new line.
(write-char char port)
It outputs the char to the port.
转自:http://www.shido.info/lisp/scheme9_e.html
scheme 提供了一些输入输出过程,可以调用它们读取输入端口,写入输出端口,而这些端口<port>可以与控制台<console>、文件<file>或者字符串<string>相关联。
 
1.Reading<读取>
 
scheme 读取<reader>过程有一个可选输入端口参数,默认是当前输入端口<通常是控制台>。
 
读取可以是基于字符、行或者是符号表达式。在每一次读取过程中,端口的状态都会更新,以使下一次读取时从已经读过的后面开始。如果一个端口已经读取到结尾,读取过程就返回 end-of-file 或 eof-object 对象,这个对象可以用 eof-object? 函数来判断。
  • read-char 过程读取指定端口下一个字符;
  • read-line 过程读取指定端口的下一行,返回一个字符串<换行符会自动去掉>;
  • read 过程读取指定端口的下一个符号表达式。
2.Writing<写入>
 
scheme 写入过程以一个被写入对象和一个可选输出端口为参数,输出端口默认是当前输出端口<通常为控制台>。
  • write-char 过程把一个字符<不带 #\>写入到指定端口;
  • write 过程把一个符号表达式以一种 machine-readable 的形式写入指定端口,比如,一个字符串会被双引号括着,而字符会带有 #\;
  • display 过程把一个符号表达式以一种 human-readable 的形式写入指定端口,比如,一个字符串不会被双引号括着,而一个字符不会带有 #\。
3.File ports<文件端口>
 
scheme 输入(输出)过程以标准输入(输出)为默认输入(输出)端口,所以当从标准输入(输出)读取(写入)时,不用指定端口,但是如果你想显式的给出端口,可以调用无参数的 current-input-port 和 current-out-port 过程:
1
2
3
scheme@(guile-user)> (display 9)
9scheme@(guile-user)> (display 9 (current-output-port))
9scheme@(guile-user)>
  • open-input-file 以一个文件名为参数,返回与这个文件相关联的输入端口,当所给文件不存在时会报错;
  • open-output-file 以一个文件名为参数,返回与这个文件相关联的输出端口,当所给文件已存在时会报错。
当对一个端口完成所有操作时,你应当用 close-input-port 和 close-output-port 来关闭它。
 
下面例子中,假设当前文件夹下 hello.txt 文件只含有 hello 一个词:
scheme@(guile-user)> (define i (open-input-file "hello.txt"))
scheme@(guile-user)> (read-char i)
#\h
scheme@(guile-user)> (define j (read i))
scheme@(guile-user)> j
ello
scheme@(guile-user)> (read-char i)
#\newline
scheme@(guile-user)> (read-char i)
#<eof>
下面例子,假设当前文件夹下没有 greeting.txt 文件:
1
2
3
4
5
6
scheme@(guile-user)> (define o (open-output-file "greeting.txt"))
scheme@(guile-user)> (display "hello" o)
scheme@(guile-user)> (write-char #\space o)
scheme@(guile-user)> (display 'world o)
scheme@(guile-user)> (newline o)
scheme@(guile-user)> (close-output-port o)
此时,在当前文件夹下会有一个 greeting.txt 文件,文件内容为:hello world
 
3.1 Automatic opening and closing of file ports<自动开关文件端口>
 
scheme 中的 call-with-input-file 和 call-with-output-file 过程会为你自动打开一个端口,并且当你不再用它时会自动关闭它。
 
call-with-input-file 过程以一个文件名和一个过程为参数,而参数过程是以一个端口为参数,而 call-with-input-file 过程的作用就是把与一个文件名相关的端口传给其过程参数,并且当过程参数返回时确保该端口被关闭:
scheme@(guile-user)> (call-with-input-file "hello.txt"
...                     (lambda (i)
...                        (let* ((a (read-char i))
...                               (b (read-char i))
...                               (c (read-char i)))
...                           (list a b c))))
(#\h #\e #\l)
call-with-output-file 过程与 call-with-input-file 过程相似,但是其所服务的对象是输出文件。
 
4.String ports<字符串端口>
 
open-input-string 过程使一个字符串与一个端口相关联,而那些读取过程对该端口的操作就是读出字符串中的内容:
scheme@(guile-user)> (define i (open-input-string "hello world"))
scheme@(guile-user)> (read-char i)
#\h
scheme@(guile-user)> (read i)
ello
scheme@(guile-user)> (read i)
world
scheme@(guile-user)> (read i)
#<eof>
 
5.Loading file<加载文件>
 
load 过程会在当前模块中顺序执行当前文件夹下给定文件名中所有 scheme 语句。

参考:
http://www.shido.info/lisp/scheme9_e.html

http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-9.html

http://lispor.is-programmer.com/posts/23271.html

scheme I/0 输入输出操作的更多相关文章

  1. 24小时学通Linux内核之如何处理输入输出操作

    真的是悲喜交加呀,本来这个寒假早上8点都去练车,两个小时之后再来实验室陪伴Linux内核,但是今天教练说没名额考试了,好纠结,不过想想就可以睡懒觉了,哈哈,自从大三寒假以来还没睡过懒觉呢,现在也有更多 ...

  2. 十天学Linux内核之第四天---如何处理输入输出操作

    原文:十天学Linux内核之第四天---如何处理输入输出操作 真的是悲喜交加呀,本来这个寒假早上8点都去练车,两个小时之后再来实验室陪伴Linux内核,但是今天教练说没名额考试了,好纠结,不过想想就可 ...

  3. Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤

    原文地址: Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤 - 网络资源是无限的 - 博客频道 - CSDN.NET http://blog.csdn.net/fen ...

  4. Ubuntu14.04 64位机上安装OpenCV2.4.13(CUDA8.0)版操作步骤

    Ubuntu14.04 64位机上安装CUDA8.0的操作步骤可以参考http://blog.csdn.net/fengbingchun/article/details/53840684,这里是在已经 ...

  5. unix的输入输出操作

    unix的输入输出操作 使用的头文件 #include <unistd.h> #include <stdio.h> 函数说明 ssize_t read(int fd, void ...

  6. ThinkPHP5.0框架开发--第7章 TP5.0数据库操作

    ThinkPHP5.0框架开发--第7章 TP5.0数据库操作 第7章 TP5.0数据库操作 ===================================================== ...

  7. moloch1.8.0简单操作手册

    moloch1.8.0简单操作手册 Sessions 页面:Sessions主要通过非常简单的查询语言来构建表达式追溯数据流量,以便分析. SPIView 页面: SPIGraph页面:SPIGrap ...

  8. mysql8.0.16操作记录

    mysql8.0.16操作记录 2.1.登录 -uroot -p'AnvcTMagdLarwNV3CKaC' mysql: [Warning] Using a password on the comm ...

  9. Lua I/0输入输出

    I/O库为文件操作提供了两种不同的模型,简单模型和完整模型.简单模型假设一个当前输入文件和一个当前输出文件,他的I/O操作均作用于这些文件.完整模型则使用显式的文件句柄,并将所有的操作定义为文件句柄上 ...

随机推荐

  1. oracle pipelined返回值函数 针对数据汇总统计 返回结果集方法

    近期需要一个汇总统计,由于数据太多,数据量太大所以在java程序中实现比较困难.若用后台程序统计,数据不能保证实时,同时实现周期比较长.顾使用函数返回结果集的方式,在不增加临时表的情况下实时获取数据. ...

  2. 【转】vsftp 遇到错误 500 OOPS: vsftpd: refusing to run with writable root inside chroot()--不错

    原文网址:http://linux.it.net.cn/e/server/ftp/2015/0227/13554.html 当我们限定了用户不能跳出其主目录之后,使用该用户登录FTP时往往会遇到这个错 ...

  3. Spiral Matrix 解答

    Question Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in ...

  4. 【转】Alsa音频编程【精华】

    一.前序 这里了解一下各个参数的含义以及一些基本概念. 声音是连续模拟量,计算机将它离散化之后用数字表示,就有了以下几个名词术语. 样本长度(sample):样本是记录音频数据最基本的单位,计算机对每 ...

  5. DM6437 dsp系列之启动过程全析(2)—AIS文件解析

    本文均属自己阅读源码的点滴总结,转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email: gzzaigcn2009@163.com,gzzaigcn2012@gmail.com ...

  6. VC皮肤库SkinSharp 1.0.6.6的使用

    SkinSharp又称Skin#,是Windows环境下一款强大的换肤组件. SkinSharp作为换肤控件,仅仅须要在您的程序中加入一行代码,就能让您的界面焕然一新,并拥有多种主题风格和色调的动态切 ...

  7. C/C++笔试准备(1)

    题目:用递归的算法实现这样一个函数,计算一个字符串最大连续相同字符数,输入aaabbc,输出3:输入bbc,输出2 #include <iostream> using namespace ...

  8. EffectiveC#6--区别值类型数据和引用类型数据

    1. 设计一个类型时,选择struct或者class是件简单的小事情,但是,一但你的类型发生了改变, 对所有使用了该类型的用户进行更新却要付出(比设计时)多得多的工作. 2.值类型:无多态但性能佳. ...

  9. [转]CSS vertical-align属性详解 作者:黄映焜

      CSS vertical-align属性详解 posted @ 2014-08-26 17:44 黄映焜   前言:关于vertical-align属性. 实践出真知. 垂直居中. 第二种用法. ...

  10. 鼠标滚轮(mousewheel)和DOMMouseScroll事件

    IE6.0首先实现了mousewheel事件.此后,Opera.Chrome和Safari也都实现了这个事件.当用户通过鼠标滚轮与页面交互.在垂直方向上滚动页面时(无论向下还是向上),就会触发mous ...