<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; 函数式编程</title>
	<atom:link href="https://www.phppan.com/tag/%e5%87%bd%e6%95%b0%e5%bc%8f%e7%bc%96%e7%a8%8b/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sat, 25 Apr 2026 00:56:17 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>Scheme学习笔记2: 输入和输出</title>
		<link>https://www.phppan.com/2011/12/scheme-study-02-input-and-output/</link>
		<comments>https://www.phppan.com/2011/12/scheme-study-02-input-and-output/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 01:16:00 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[程序相关]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[ZOJ]]></category>
		<category><![CDATA[函数式编程]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1545</guid>
		<description><![CDATA[本文包括以下内容： read和write 字符操作 文件操作 作为一门语言，它需要提供与外设交互的方式，在各种 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文包括以下内容：</p>
<ul>
<li><a href=#1>read和write</a></li>
<li><a href=#2>字符操作</a></li>
<li><a href=#3>文件操作</a></li>
</ul>
<p>作为一门语言，它需要提供与外设交互的方式，在各种语言中都提供了输入输出，Scheme语言也不例外。Scheme语言的输入输出功能，是在C基础上的一种封装。</p>
<p><a name="1"></a><strong>read和write</strong></p>
<p>
输入输出中我们常用是读和写，对应读与写，在Scheme中有read和write。<br />
read是读操作，它将 Scheme 对象的外部表示转换为对象本身。<br />
read的标准格式为：(read port)<br />
其中port参数可以省略，此时它使用的默认是current-input-port的返回值。
</p>
<p>
write是写操作，它的标准格式为：(read obj port)<br />
write过程的作用是向给定端口port输出obj的内容。其中输出内容的反斜线、双引号等会被反斜线转义。write的参数中port参数可以省略，默认情况下使用current-output-port的返回值。
</p>
<p>这里的默认值我们可以对应到标准输入和输出。从ZOJ的第一题我们看下read的使用。<br />
如下代码：</p>
<p>ZOJ第一题(<a href="http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1001">zoj1001</a>)：</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>main<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>a <span style="color: #66cc66;">&#40;</span>read<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>b <span style="color: #66cc66;">&#40;</span>read<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span><span style="color: #66cc66;">&#40;</span>eof-object? a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>begin
<span style="color: #66cc66;">&#40;</span>display <span style="color: #66cc66;">&#40;</span>+ a b<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>newline<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>main<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>main<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
题目很简单，就是输入两个数，输出和。这里的难点是对于输入结束的判断，在C语言中scanf函数有一个EOF的判断，而在Scheme语言中，我们通过判断输入的输入的值是否为eof来判断，其对应的判断过程为eof-object?（嗯，问号也是调用过程的组成部分，个人非常喜欢这种表达方式），在判断不为结束时继续递归调用，实现C语言中的while循环。
</p>
<p>
<a name="2"></a><strong>字符操作</strong></p>
<p>
对于字符的读写操作，我们常用的三个过程如下：
</p>
<p>
read-char<br />
标准格式：　(read-char port)<br />
读取一个字符，并将port指针指向下一个字符。<br />
read-char的参数中port可以省略，默认情况下使用current-input-port的返回值。
</p>
<p>
write-char<br />
标准格式：　(write-char port)<br />
write-char过程的作用是向给定端口port输出的内容。<br />
write-char的参数中port可以省略，默认情况下使用current-output-port的返回值。
</p>
<p>
peek-char<br />
标准格式：　(peek-char port)<br />
获取一个字符，但并不将port指针指向下一个字符<br />
peek-char的参数中port可以省略，默认情况下使用current-input-port的返回值。
</p>
<p>以一个示例说明这三个过程的调用，示例实现从指定文件中按字符读取内容，并放到一个列表中。</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define input_port <span style="color: #66cc66;">&#40;</span>open-input-file <span style="color: #ff0000;">&quot;temp&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define read-char-with-file <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>port<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>eof-object? <span style="color: #66cc66;">&#40;</span>peek-char port<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
'<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cons</span> <span style="color: #66cc66;">&#40;</span>read-char port<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>read-char-with-file port<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>input-port? input_port<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>begin
<span style="color: #66cc66;">&#40;</span>display <span style="color: #66cc66;">&#40;</span>read-char-with-file input_port<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>close-input-port input_port<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>begin
<span style="color: #66cc66;">&#40;</span>display <span style="color: #ff0000;">&quot;read file form temp failed&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>newline<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>
这段代码写得有些复杂，我们可以通过let关键字和call-with-input-file过程来简化这段代码，如下：
</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define output-chars
<span style="color: #66cc66;">&#40;</span>call-with-input-file <span style="color: #ff0000;">&quot;temp&quot;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>p<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> f <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>read-char p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>eof-object? x<span style="color: #66cc66;">&#41;</span>
'<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cons</span> x <span style="color: #66cc66;">&#40;</span>f <span style="color: #66cc66;">&#40;</span>read-char p<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> 
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>display output-chars<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>newline<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>call-with-input-file的标准调用格式为：</p>
<p>procedure: (call-with-input-file path procedure)</p>
<p>
 call-with-input-file过程给指定的文件创建一个port，并将这个port传递给第二个参数指定的过程procedure，当procedure执行完成时，call-with-input-file过程将关闭打开的输入port并返回procedure返回的值。
</p>
<p></p>
<p><a name="3"></a><strong>文件操作</strong></p>
<p>
上面的示例已经提了文件操作，关于文件操作，除了针对输入和输出的打开port和关闭port，判断port是否存在的过程外，我们常用还有判断文件存在，删除文件，Scheme提供的这两个过程来与文件系统交互：file-exists?和delete-file<br />
file-exists?的作用是判断文件是否存在，其调用格式如下：<br />
(file-exists? path)<br />
如果文件存在，返回#t，否则返回#f
</p>
<p>
delete-file的作用是删除一个文件，其调用格式如下：<br />
(delete-file path)</p>
<p>path是字符串类型，如果所给的文件不存在，则会显示错误：No such file or directory</p>
<p>在使用delete-file之前可以调用file-exists?来判断文件是否存在。
</p>
<p>除了上面介绍的一些简单输入输出，Scheme还提供了更强大和灵活的输入输出机制，如对编码的处理，对二进制的处理，对字符串的操作等，具体可以见官方文档或《The Scheme Programming Language, 4th Edition》</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2011/12/scheme-study-02-input-and-output/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
