Next: Interpretation and Compilation Semantics and Immediacy Tutorial, Previous: Floating Point Tutorial, Up: Tutorial
This section gives a short introduction into how to use files inside Forth. It's broken up into five easy steps:
Reference: General files.
s" foo.in" r/o open-file throw Value fd-in
s" foo.out" w/o create-file throw Value fd-out
The available file modes are r/o for read-only access, r/w for
read-write access, and w/o for write-only access. You could open both
files with r/w, too, if you like. All file words return error codes; for
most applications, it's best to pass there error codes with throw
to the outer error handler.
If you want words for opening and assigning, define them as follows:
0 Value fd-in 0 Value fd-out : open-input ( addr u -- ) r/o open-file throw to fd-in ; : open-output ( addr u -- ) w/o create-file throw to fd-out ;
Usage example:
s" foo.in" open-input s" foo.out" open-output
256 Constant max-line Create line-buffer max-line 2 + allot : scan-file ( addr u -- ) begin line-buffer max-line fd-in read-line throw while >r 2dup line-buffer r> compare 0= until else drop then 2drop ;
read-line ( addr u1 fd -- u2 flag ior )
reads up to u1 bytes into
the buffer at addr, and returns the number of bytes read, a flag that is
false when the end of file is reached, and an error code.
compare ( addr1 u1 addr2 u2 -- n )
compares two strings and
returns zero if both strings are equal. It returns a positive number if
the first string is lexically greater, a negative if the second string
is lexically greater.
We haven't seen this loop here; it has two exits. Since the while
exits with the number of bytes read on the stack, we have to clean up
that separately; that's after the else
.
Usage example:
s" The text I search is here" scan-file
: copy-file ( -- ) begin line-buffer max-line fd-in read-line throw while line-buffer swap fd-out write-line throw repeat ;
fd-in close-file throw fd-out close-file throw
Likewise, you can put that into definitions, too:
: close-input ( -- ) fd-in close-file throw ; : close-output ( -- ) fd-out close-file throw ;
Assignment: How could you modify copy-file
so that it copies until a second line is
matched? Can you write a program that extracts a section of a text file,
given the line that starts and the line that terminates that section?