上下文:
我有一个名为 fr.txt
的文本文件其中包含 3 列文本:
65 A #\A
97 a #\a
192 À #\latin_capital_letter_a_with_grave
224 à #\latin_small_letter_a_with_grave
etc...
我想创建一个函数来读取第一列(最终也是第三列)并将其写入另一个名为 alphabet_code.txt
的文本文件中.
到目前为止我有这个功能:
(defun alphabets()
(setq source (open "fr.txt" :direction :input :if-does-not-exist :error))
(setq code (open "alphabet_code.txt" :direction :output :if-does-not-exist :create :if-exists :supersede))
(loop
(setq ligne (read-line source nil nil))
(cond
((equal ligne nil) (return))
(t (print (read-from-string ligne) code))
)
)
(close code)
(close source)
)
我的问题:
我不太明白read-line函数的参数是怎么来的。我读过this doc ,但它对我来说仍然很模糊。如果有人有非常简单的示例,那将会有所帮助。
使用当前代码,我得到这个错误:
*** - read: input stream #<input string-input-stream> has reached its end
即使我改变了nil nil
在(read-line source nil nil)
其他值。
感谢您的宝贵时间!
最佳答案
您的问题
read-line
可选参数
read-line
接受 3 个可选参数:
eof-error-p
:在 EOF 上做什么(默认:错误)eof-value
:看到 EOF 时返回什么而不是错误recursive-p
:你是从你的print-object
调用它吗?方法(暂时忘掉这个)
例如,当 stream
处于 EOF 时,
(read-line stream)
将发出end-of-file
信号错误(read-line stream nil)
将返回nil
(read-line stream nil 42)
将返回42
。
请注意,(read-line stream nil)
与 (read-line stream nil nil)
相同,但人们通常仍显式传递第二个可选参数。
nil
的 eof-value
适用于 read-line
因为 nil
不是字符串并且 read -line
只返回字符串。
另请注意,在 read
的情况下第二个可选参数通常是 stream
本身:(read stream nil stream)
。很方便。
错误
您收到来自 read-from-string
的错误, 不是 read-line
,因为很明显,您的文件中有一个空行。
我知道是因为错误提到了 string-input-stream
, 不是 file-stream
.
你的代码
您的代码在功能上是正确的,但在风格上却大错特错。
- 你应该使用
with-open-file
只要有可能。 - 你不应该使用
print
在代码中,它是一个奇怪的遗留函数,主要用于交互使用。 - 不能用
setq
创建局部变量- 使用let
或其他等效形式(在这种情况下,您永远不需要let
!:-)
以下是我将如何重写您的函数:
(defun alphabets (input-file output-file)
(with-open-stream (source input-file)
(with-open-stream (code output-file :direction :output :if-exists :supersede)
(loop for line = (read-line source nil nil)
as num = (parse-integer line :junk-allowed t)
while line do
(when num
(write num :stream code)
(write-char #\Newline code))))))
(alphabets "fr.txt" "alphabet_code.txt")
查看文档:
-
loop
:for/as
,while
,do
-
write
,write-char
-
parse-integer
或者,我可以使用相应的 loop
conditional 而不是 (when num ...)
.
此外,我可以编写 (format code "~D~%"num)
而不是 write
+write-char
。
请注意,我没有传递那些与默认值相同的with-open-stream
参数。
默认设置是一成不变的,您编写的代码和用户阅读的代码越少,出错的可能性就越小。
关于file-io - 到达eof时,读取行在Lisp中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42102947/