ファイルへ出力

昨日はファイルからの入力を覚えたので、今日はファイルへの出力。

 cf. 9. 入出力 – もうひとつの Scheme 入門

open-output-file、close-output-port

(open-output-file filename) は filename を出力用に開いてポートを返す。使い終わったら (close-output-port port) でポートを閉じる。
出力は display。newline で改行する。

(define write-to-file
  (lambda (file-name message)
    (let ((p (open-output-file file-name)))
      (begin
        (display message p)
        (newline p)
        (close-output-port p)))))

実行例:

gosh> (load "write-to-file1.scm")
#t
gosh> (write-to-file "hello1.txt" "Hello, world.")
#<undef>
gosh> (exit)

^o^ > type hello1.txt
Hello, world.

call-with-output-file

(call-with-output-file filename procedure) は filename を出力用に開いて procedure を評価する。procedure はポートを引数に取る関数。

(define write-to-file
  (lambda (file-name message)
    (call-with-output-file file-name
      (lambda (p)
        (begin
          (display message p)
          (newline p)
          (close-output-port p))))))

実行例:

gosh> (load "write-to-file2.scm")
#t
gosh> (write-to-file "hello2.txt" "Hello, scheme.")
#<undef>
gosh> (exit)

^o^ > type hello2.txt
Hello, scheme.

with-output-to-file

(with-output-to-file filename procedure) は filename を標準入力として開き、procedure を評価する。procedure は引数なしの関数。終わったらポートは勝手に閉じられる。

(define write-to-file
  (lambda (file-name message)
    (with-output-to-file file-name
      (lambda ()
        (begin
          (display message)
          (newline))))))

実行例:

gosh> (load "write-to-file3.scm")
#t
gosh> (write-to-file "hello3.txt" "Hello, world. This is scheme.")
#<undef>
gosh> (exit)

^o^ > type hello3.txt
Hello, world. This is scheme.

練習:ファイルからの入力

ファイルからの入力の練習。

 cf. 9. 入出力 – もうひとつの Scheme 入門

の練習問題1。

ファイルの内容を1行ずつのリストにして返す関数 read-lines を書いてください。 hello.txt に適用すると次のようになるようにして下さい。’\n’ は #\Newline です。 改行文字は残すようにしてください。

(read-lines “hello.txt”) ⇒ (“Hello world!\r\n” “Scheme is an elegant programming language.\r\n”)

(define read-lines
  (lambda (file-name)
    (let ((p (open-input-file file-name)))
      (let loop ((lines '()) (line '()) (c (read-char p)))
        (cond
          ((eof-object? c)
           (begin
             (close-input-port p)
             (reverse lines)))
          ((eq? c #\Newline) (loop (cons (list->string (reverse (cons c line))) lines) '() (read-char p)))
          (else (loop lines (cons c line) (read-char p))))))))

実行例:

^o^ > gosh -I.
gosh> (load "read-lines.scm")
#t
gosh> (read-lines "sample.txt")
("Hello world!\r\n" "Scheme is an elegant programming language.\r\n")