使用Scheme从文件中读取

Bar*_*ttt 7 file-io scheme

我正在尝试使用scheme读取文件,并将其内容放入列表中.

问题是如何删除问号,数字,并保持单词.我应该每次使用循环检查吗?如果不是这样的话,我如何从"阅读"中获取下一个单词的内容?

我尝试使用此代码解决它,但我找不到一种方法来调用"读取"直到获得文件结束;

(define Project
  (lambda (fileName)
    (if (null? fileName) 
        'error
        (readNext (open fileName) '()))))

(define readNext
  (lambda (fc tmp)
    (if (null? (read fc) "#<eof>")
        tmp
        (readNext fc (cons (read fc) tmp)))))
Run Code Online (Sandbox Code Playgroud)

Wil*_*ill 11

导入文本的最佳推荐方法是编辑文件并将其另存为定义变量的方案文件:

(define data "the text in
mydata.scm here")
Run Code Online (Sandbox Code Playgroud)

然后打电话:

(load "mydata.scm")
Run Code Online (Sandbox Code Playgroud)

很多时候,并非每个数据文件都可以编辑并保存为方案文件,并且当换行符自动转义时,双引号不能,这会在加载文件时产生问题.

一些特定于实现的技术是:

;Chicken
(use utils)
(read-all "mydata.txt")

;Racket
(file->string "mydata.txt")
Run Code Online (Sandbox Code Playgroud)

更便携的功能是:

;works in chicken-csi and Racket
(define (readlines filename)
  (call-with-input-file filename
    (lambda (p)
      (let loop ((line (read-line p))
                 (result '()))
        (if (eof-object? line)
            (reverse result)
            (loop (read-line p) (cons line result)))))))
Run Code Online (Sandbox Code Playgroud)

运行可执行文件编译的chicken-csc会因读取行需要额外文件而产生错误.

读取文件最便携的方法是这个功能:

;works in Chicken, Racket, SISC
;Read a file to a list of chars
(define (file->char_list path)
 (call-with-input-file path
   (lambda (input-port)
     (let loop ((x (read-char input-port)))
       (cond 
        ((eof-object? x) '())
        (#t (begin (cons x (loop (read-char input-port))))))))))
Run Code Online (Sandbox Code Playgroud)

该功能在各种实现中相当快速且可移植.所需要的只是将char_list转换为字符串.

最简单的方法是:

;may not work if there is limit on arguments
(apply string (file->char_list "mydata.txt"))
Run Code Online (Sandbox Code Playgroud)

问题是一些实现对可以传递给函数的参数数量有限制.2049个字符列表在鸡肉中不起作用.

另一种方法是:

;works in Chicken, Racket
(foldr (lambda (x y) (string-append (string x) y)) "" (file->char_list "mydata.txt"))
Run Code Online (Sandbox Code Playgroud)

问题是:首先,尽管可以定义,但折叠并不是普遍认可的(SISC).其次,由于追加每个字符,这种方法非常慢.

我编写了接下来的两个函数来将一个字符列表分割成嵌套列表,直到最低级别不超过Chicken中的最大参数计数.第三个函数遍历嵌套的char列表,​​并使用字符串string-append返回一个字符串:

(define (cleave_at n a)
  (cond
   ((null? a) '())
   ((zero? n) (list '() a))
   (#t 
    ((lambda (x)
      (cons (cons (car a) (car x)) (cdr x)))
     (cleave_at (- n 1) (cdr a))))))

(define (cleave_binary_nest n a)
 (cond
  ((equal? n (length a)) (list a))
  (#t 
   ((lambda (x)
     (cond
      ((> (length (car x)) n) (map (lambda (y) (cleave_binary_nest n y)) x))
      (#t x)))
    (cleave_at (floor (/ (length a) 2)) a)))))

(define (binary_nest_char->string a)
 (cond
  ((null? a) "")
  ((char? (car a)) (apply string a))
  (#t (string-append
    (binary_nest_char->string (car a)) (binary_nest_char->string (cdr a))))))
Run Code Online (Sandbox Code Playgroud)

该函数调用如下:

;Works in Racket, Chicken, SISC
;faster than foldr method (3x faster interpreted Chicken) (30x faster compiled Chicken) (125x faster Racket gui)
(binary_nest_char->string (cleave_binary_nest 2048 (file->char_list "mydata.txt")))
Run Code Online (Sandbox Code Playgroud)

要减少字母字符和空格,还有两个功能:

(define (alphaspace? x)
 (cond
  ((and (char-ci>=? x #\a) (char-ci<=? x #\z)) #t)
  ((equal? x #\space) #t)
  (#t #f)))

(define (filter pred lis)
  ; if lis is empty
  (if (null? lis)
    ; return an empty list
    '()
    ; otherwise, if the predicate is true on the first element
    (if (pred (car lis))
      ; return the first element concatenated with the
      ; result of calling filter on the rest of lis
      (cons (car lis) (filter pred (cdr lis)))
      ; otherwise (if the predicate was false) just
      ; return the result of filtering the rest of lis
      (filter pred (cdr lis)))))

(define data (file->char_list "mydata.txt"))
(define data_alphaspace (filter alphaspace? data))
(define result (binary_nest_char->string (cleave_binary_nest 2048 data_alphaspace)))
Run Code Online (Sandbox Code Playgroud)

这适用于Racket,Chicken(解释和编译)和SISC(Java).每种方言都应该适用于Linux,Mac(OS X)和Windows.


GoZ*_*ner 5

也许这会让你开始.

(define (file->list-of-chars file)
  (with-input-from-file file
    (lambda ()
      (let reading ((chars '()))
        (let ((char (read-char)))
          (if (eof-object? char)
              (reverse chars)
              (reading (cons char chars))))))))
Run Code Online (Sandbox Code Playgroud)