lisp - 使用 read-line 从 .txt 中读取,正在读取其他符号。记事本神器?

标签 lisp common-lisp

以下是考试作业/备考的一部分:我正在尝试编写一些 clisp 代码来从文本文件中读取行。应包括空行。以下是我想出的代码:

(defun read-file (filename)
   (do* ((streamin (open filename))               ;open the file
        content
        (line (read-line streamin nil 'eof)      ;read from file in loop
               (read-line streamin nil 'eof)))
        ((equal line 'eof) (close streamin)       ;close the stream if eof is reached
        (reverse content))
    (setq content (cons line content))))         ;add a read line to the returned symbol

在 sublime 文本编辑器(或记事本)中创建的文本文件的预期输出如下所示:

this is

a

test
file

这是:

("this is" "" "a" "" "test" "file")

但是,我收到以下信息:

("this is^M" "^M" "a^M" "^M" "test^M" "file^M")

“^M”从何而来?它们是用记事本插入的吗?或者他们在那里是因为我的代码?它们到底是什么?我猜它们表示换行。

如果它们是由 sublime 插入的,我有什么替代方法来创建预期的输出?记事本也是如此。练习的下一步是使用过滤函数从输出中删除空行,我想这可以通过比较等于空行的行来实现。但是,当插入这些 ^M 时这是不可能的,因为例如

(equal "^M" (read-line test_file_with_empty_lines))

返回零。而

(equal "^M" "^M")

显然返回 T...

最佳答案

您正在使用期望 Unix 行结束约定的系统读取具有 DOS 行结束约定的文件。

DOS 以回车/换行对结束行。回车的ASCII码为#x0d/13,即控件M,换行符为#x0a/10,即控件J。

这些字符的 CL 名称(我应该在上面使用)分别是 #\Return#\Newline

因此,具有 DOS 行结束约定的文件将包含诸如(十六进制)0d0a 之类的序列来标记行结束。一些期望 Unix 行结束约定(只是一个 0a)的东西会把它读成最后一个字符是 #\Return 的行。

处理此问题的方法是以下三件事之一:

  • 假设您在 Unixy 机器上运行,使用使用 Unixy 行尾约定的编辑器(无论如何 Sublime Text 都在 OSX 上);
  • 如果您使用的是 Windows 机器,那么 Lisp 可能应该默认采用该平台的 native 行尾约定并为您翻译;
  • 如果以上一个或两个都不起作用,或者文件已在机器之间移动,您需要阅读open 的实现文档,以了解如何教它使用适当的读取 DOS 约定文件的外部格式。

看来您正在使用 CLISP。如果是这样,并且如果我正确阅读了它的手册,您可能想使用类似 (open ... :external-format ':dos) 的东西。


作为附加说明,虽然您的代码有效,但它不是很惯用的 CL,而且也不安全(如果读取文件时出错会怎样?):您可能希望查看规范的第 21.2 节。 (我故意不给你答案,因为你老实说,这是作业,谢谢!)。

关于lisp - 使用 read-line 从 .txt 中读取,正在读取其他符号。记事本神器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57053601/

相关文章:

lisp - 符号处理 : cannot compare for identity

functional-programming - 计划作业

prolog - 将 Prolog 代码翻译成 Lisp

lisp - Common Lisp 中的跨包 defgeneric/defmethod?

arrays - 两个数组 LISP 的两个值之和

list - 使用通配符比较列表

perl - 是否可以在 Perl 6 中实现 lisp "language"?

lisp - ltk 的问题(普通 lisp)

macros - lisp:何时使用函数与宏

common-lisp - 获取asdf以加载目录中的所有文件