微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从通用Lisp文件中仅读取两个整数

如何解决如何从通用Lisp文件中仅读取两个整数

(defun read-file (filename)
    (with-open-file (stream filename)
        (loop for line = (read-line stream nil)
            while line
                collect line)
    )
)

我对Lisp完全陌生,所以我想逐整数读取整数,但是我逐行编写这段代码。 所以我找不到那个。

用于展示我的文件

10 20

我需要帮助.thx

解决方法

OP的目标似乎是从文件中读取行,每行包含一对整数,并返回包含从文件中读取的所有整数的列表。

给出一个输入文件numbers.dat

10 20
30 40
50 60
70 80
90 100

可以使用read-line将文件读入列表:

CL-USER> (with-open-file (in "numbers.dat" :direction :input)
           (loop :for line := (read-line in nil)
                 :while line
                 :collect line))
("10 20" "30 40" "50 60" "70 80" "90 100" "")

但是现在列表包含字符串,并且每个字符串对应于一对整数。我们需要一个函数从字符串中提取整数。 Common Lisp具有函数read-from-string,该函数解析包含对象的打印表示形式的字符串,并返回该对象和输入字符串的第一个未读位置。此函数可用于循环中,以从输入字符串中提取整数:

CL-USER> (loop :with num
               :and pos := 0
               :do (setf (values num pos)
                         (read-from-string "10 20" t nil :start pos))
               :collect num
               :until (= pos 5))
(10 20)

如果将此代码删除到可以处理不同长度的字符串和空字符串的函数,并映射到("10 20" "30 40" "50 60" "70 80" "90 100" "")之类的输入列表上,那么我们将以((10 20) (30 40) (50 60) (70 80) (90 100) ())接近目标。可以将此类列表的内容附加在一起,以从文件中获取所需的所有整数列表:

;;; Expects well-behaved input
(defun get-numbers-from-string (string)
  (if (string= string "")  ; empty string returns empty list
      '()
      (let ((*read-eval* nil)  ; small precaution to guard against malicious input
            (length (length string)))
        (loop :with num      ; number from STRING
              :and pos := 0  ; next position in STRING to read from
              :do (setf (values num pos)
                        (read-from-string string t nil :start pos))
              :collect num
              :until (= pos length)))))

(defun read-integer-pairs (filename)
  (with-open-file (in filename
                      :direction :input)
    (apply #'append  ; combine sublists into a single list of numbers
           (mapcar #'get-numbers-from-string  ; transform strings to number pairs
                   (loop :for line := (read-line in nil)
                         :while line
                         :collect line)))))

示例互动:

CL-USER> (read-integer-pairs "numbers.dat")
(10 20 30 40 50 60 70 80 90 100)
,

不确定您要问的是什么,因此这是一个简短的建议,即将文件读取为字符串,用空格分隔,然后用parse-integer解析每个数字:

(mapcar #'parse-integer (str:words (uiop:read-file-string "foo.txt")))

uiop来自ASDF,并包含在所有主要实现中,str是一个用于快速加载的库。

uiop也有read-file-lines

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。