MIT スキームには がありstring->input-port
、ラケットには がありopen-input-string
ます。これを純粋なスキームで実装する方法 (Racket、Chicken、Gambit、または実装固有の拡張機能はありません)。
質問する
243 次
3 に答える
1
Chis の回答によると、新しいスキーム標準 R7RS があります。提供してきopen-input-string
た。
古い R6RS の場合、ライブラリからmake-custom-textual-input-portを使用して同じことを実装するのは簡単です。(rnrs io ports (6))
ここに私がまとめたものがあります:
#!r6rs
(import (rnrs base (6))
(rnrs io ports (6))
(rnrs mutable-strings (6))
(rnrs io simple (6)))
(define (open-input-string str)
;; might not be so important to have a different indentifier
;; but this will make debugging easier if implementations use the
;; id provided
(define get-id
(let ((n 0))
(lambda (str)
(set! n (+ n 1))
(string->symbol
(string-append "string-port" str "-"
(number->string n))))))
(let ((len (string-length str))
(pos 0))
(make-custom-textual-input-port
(get-id str)
(lambda (string start count)
(let loop ((cur-dst start)
(cur-src pos)
(n 0))
(cond ((or (>= cur-src len)
(>= n count))
(set! pos cur-src)
n)
(else
(string-set! string cur-dst (string-ref str cur-src))
(loop (+ cur-dst 1)
(+ cur-src 1)
(+ n 1))))))
(lambda () pos)
(lambda (new-pos) (set! pos new-pos))
#f)))
(define test (open-input-string "(1 2 3 4)(5 6 7 8)"))
(define str (read test)) ; str == (1 2 3 4)
(define str2 (read test)) ; str2 == (5 6 7 8)
R5RS
ファイルを使用する以外にこれを行う方法はありません。
于 2013-11-08T16:32:35.407 に答える
-2
文字列を (一時) ファイルに書き込み、入力ポートを返してそれを読み戻します。次のようにします。
(define (open-input-string string)
(let ((file "/tmp/foo"))
(call-with-output-file file
(lambda (port)
(display string port)))
(open-input-file file)))
> (define ps (open-input-string "This is a test; it is only a test"))
> ps
#<input-port (textual) "/tmp/foo">
> (read-line ps)
"This is a test; it is only a test"
を使用するには、より洗練されている必要があることに注意してくださいfile
。たとえば、上記のコードは一度しか機能しません。2 回目の呼び出しで「ファイルが存在します」で失敗します。しかし、上記はあなたの質問に対する簡単な答えです。
于 2013-11-08T15:18:09.540 に答える