什么是交互式回复IO功能?
我学习CommonLisp已经有一段时间了,我遇到了一个问题 我如何实现这样一个功能,允许用户输入一些单词,直到用户输入退出。 (实际上我想知道什么样的命令行交互函数API适合这样的需求) e、 g。什么是交互式回复IO功能?,io,common-lisp,read-eval-print-loop,Io,Common Lisp,Read Eval Print Loop,我学习CommonLisp已经有一段时间了,我遇到了一个问题 我如何实现这样一个功能,允许用户输入一些单词,直到用户输入退出。 (实际上我想知道什么样的命令行交互函数API适合这样的需求) e、 g。 提示“请输入一个单词:”在REPL中,然后将用户输入存储到全局“我的单词”中,当用户输入“退出”时退出。您的规范有点不完整(例如,您的问题中的单词由什么组成?如果用户添加多个单词怎么办?如果输入为空怎么办?)。下面我用它将输入拆分成不同的单词,并一次将它们全部添加,因为它在一般情况下似乎很有用。在
提示“请输入一个单词:”在REPL中,然后将用户输入存储到全局“我的单词”中,当用户输入“退出”时退出。您的规范有点不完整(例如,您的问题中的单词由什么组成?如果用户添加多个单词怎么办?如果输入为空怎么办?)。下面我用它将输入拆分成不同的单词,并一次将它们全部添加,因为它在一般情况下似乎很有用。在您的情况下,您可能需要添加更多的错误检查 如果您想与用户交互,您应该在流中读写。在这里,我将根据您的要求提供一个带有全局变量的版本,以及另一个没有副作用的版本(除了输入/输出) 使用全局变量 定义全局变量并用空的可调数组初始化它。 我使用的是一个数组,这样很容易在末尾添加单词,但也可以使用队列
(defvar*my words*(生成数组10:填充指针0:可调t))
以下函数将对全局变量进行变异:
(defun副作用词repl()
(环路
(格式*查询io*“~&请输入一个单词:)
(完成输出*查询io*)
(让)字(ppcre:split
“(:1 nil:whitespace char类)
(读取行*查询io*))
(单字)
(当(字符串等于w“exit”);忽略大小写
(从副作用词repl返回)
(矢量推送扩展w*我的话*);“”)
- 使用简单语法,其中只有表达式,没有特定于循环的关键字。我首先将提示写入
。*QUERY-IO*
指令执行与相同的操作。正如雷纳在评论中指出的那样,我们必须在用户回复之前打电话确保信息得到有效打印~&
- 然后,我从同一个双向流中读取一整行,并将其拆分为一个单词列表,其中一个单词是一个非空白字符字符串
- 使用,我迭代列表,并使用将单词添加到全局数组中。但一旦我遇到
,我就终止了循环;因为我依赖于,所以测试是不敏感地进行的“exit”
(定义纯词repl()
(让((结果“()))
(环路
(格式*查询io*“~&请输入一个单词:)
(完成输出*查询io*)
(让)字(ppcre:split
“(:1 nil:whitespace char类)
(读取行*查询io*))
(单字)
(当(字符串等于w“退出”)
(从纯单词repl(nreverse结果)返回)
(推送w结果(()())))
关于单词的注释
正如jkiiski所评论的,最好在:单词边界处拆分单词。我尝试了不同的组合,下面的结果似乎满足于奇怪的示例字符串:
(mapcan(lambda(字符串)
(ppcre:拆分:字边界字符串))
(ppcre:split
“(:1 nil:whitespace char类)
“amzldk'amlzkd;:azdl-azdlk”))
=>(“amzldk”“amlzkd”“d”“;:“azdl”“azdlk”)
我首先删除所有空格,并将字符串拆分为一个字符串列表,其中可以包含标点符号。然后,每个字符串本身在:单词边界处拆分,并与连接以形成一个单独单词的列表。但是,我无法真正猜测您的实际需要是什么,因此您可能应该定义自己的拆分为单词函数来验证和拆分输入字符串。您的规范有点不完整(例如,问题中的单词是什么?如果用户添加多个单词怎么办?如果输入为空怎么办?)。下面我用它将输入拆分成不同的单词,并一次将它们全部添加,因为它在一般情况下似乎很有用。在您的情况下,您可能需要添加更多的错误检查
CL-USER 23 > (progn
(format t "~%enter a list of words:~%")
(finish-output)
(setf my-words (read))
(terpri))
enter a list of words:
(foo bar baz)
如果您想与用户交互,您应该在流中读写。在这里,我将根据您的要求提供一个带有全局变量的版本,以及另一个没有副作用的版本(除了输入/输出)
使用全局变量
定义全局变量并用空的可调数组初始化它。
我使用的是一个数组,这样很容易在末尾添加单词,但也可以使用队列
(defvar*my words*(生成数组10:填充指针0:可调t))
以下函数将对全局变量进行变异:
(defun副作用词repl()
(环路
(格式*查询io*“~&请输入一个单词:)
(完成输出*查询io*)
(让)字(ppcre:split
“(:1 nil:whitespace char类)
(读取行*查询io*))
(单字)
(当(字符串等于w“exit”);忽略大小写
(从副作用词repl返回)
(矢量推送扩展w*我的话*);“”)
- 使用简单语法,其中只有表达式,没有特定于循环的关键字。我首先将提示写入
*QUERY-IO*
。~&
指令执行与相同的操作。正如雷纳在评论中指出的那样,我们必须在用户回复之前打电话确保信息得到有效打印
- 然后,我读了一整行文章
CL-USER 28 > (loop with word = nil
do
(format t "~%enter a word or exit:~%")
(finish-output)
(setf word (read))
(terpri)
until (eql word 'exit)
collect word)
enter a word or exit:
foo
enter a word or exit:
bar
enter a word or exit:
baz
enter a word or exit:
exit
(FOO BAR BAZ)