thorso...@lavabit.com writes: > Could you show me some trivial programs related to I/O (e.g. read from > file, convert to uppercase, write to another file)?
There are many ways to do this, but here's a simple upcase program that reads the entire file into memory and does not depend on any external modules: --8<---------------cut here---------------start------------->8--- #!/usr/bin/guile \ -e main -s !# (use-modules (ice-9 match) (ice-9 rdelim)) (define (usage) (display "Usage: upcase <in-filename> <out-filename>\n") (exit 1)) (define (upcase-file in-filename out-filename) (call-with-input-file in-filename (lambda (in-port) (call-with-output-file out-filename (lambda (out-port) (display (string-upcase (read-delimited "" in-port)) out-port)))))) (define (main args) (setlocale LC_ALL "") (match args ((program in-filename out-filename) (upcase-file in-filename out-filename)) (_ (usage)))) --8<---------------cut here---------------end--------------->8--- > This page [0] doesn't list a function that can be used to read the whole > file at once. As shown in the upcase program above, (read-delimited "" port) will read the whole file as a string. You need to (use-modules (ice-9 rdelim)) to import this procedure. Most of these procedures allow you to omit the 'port' argument, in which case they will use (current-input-port) or (current-output-port). Those can be temporarily set within a block using 'with-input-from-file' and 'with-output-to-file'. For example, 'upcase-file' above could be written as follows: (define (upcase-file in-filename out-filename) (with-input-from-file in-filename (lambda () (with-output-to-file out-filename (lambda () (display (string-upcase (read-delimited "")))))))) To read one line from a file, use (read-line port), which is also from (ice-9 rdelim). For example, we can use this to modify the upcase program to read and write one line at a time, so that it will use less memory for large files (as long as the lines aren't too long): (define (upcase-file in-filename out-filename) (call-with-input-file in-filename (lambda (in-port) (call-with-output-file out-filename (lambda (out-port) (define (loop) (let ((line (read-line in-port 'concat))) (unless (eof-object? line) (display (string-upcase line) out-port) (loop)))) (loop)))))) The 'concat argument to 'read-line' means that it should include the end-of-line character(s), if any, in the returned string. By default they are stripped. Happy hacking! Mark