Held: Friday, 31 October 2003
Today we consider how to make Scheme read values and characters from
files and write values to other files.
- No reading for Monday!
- Are there questions on the exam?
- Files and ports.
- Reading values.
- Reading characters and lines.
- What did you learn yesterday?
- Why should we care about input and output?
- Your reasons:
- Here's one of mine: Once you know the I/O procedures, you can start using files.
- As I hope you've figured out by now, it is possible (although not
necessarily easy) to use Scheme to do
anything you can do
on the computer.
- Two similar things that you often want to do are to save data to files and
to recover data from files.
- So that data can last a long time.
- So that you can deal with more data than you can easily enter by hand.
- So that you can write a word processor.
- As you might guess, you can do both activites with Scheme.
- Rather than dealing directly with files, Scheme adds a layer of
abstraction called a port.
- Each port is associated with something that can be used for input
- That thing can be a file.
- That thing can also be the keyboard (for input), the screen (for
output), or a network connection.
- Why do we have ports?
- So that the process of writing anywhere (or reading anywhere) is the same; our code doesn't need to change.
- So that we can read from the same file more than once simultaneously and not get lost about where we are in the file.
- To create a port that corresponds to a file that you want to read from,
- To create a port that corresponds to a file that you want to write to,
- You can read from input ports with
- You can write to ports with
(write value port)
(display value port)
- When you're done with an input port, use
- When you're done with an output port, use
- For example, here's some code that reads one value from the file
(let* (; Prepare to read from a file
(source (open-input-file "data"))
; Read one value
(value (read source)))
; We're done, so clean up.
; Return the value read
- What does
read do when there's nothing left in the file?
It returns a special value (which DrScheme displays as
- You can tell that that value indicates the end of the file with
- Let's consider an example in which we read all the numbers in a
file and add them up.
- How do we approach the problem?
- It seems like a case for repetition, so we'll need to ask ourselves
our favorite questions about recursion.
- How do we break up the problem?
- Read the first number.
- Read the remaining numbers.
- What's the base case?
- What value do we return in that case?
- 0, the identity for addition.
- How do we write the recursive call?
- We'll figure that out later.
- What do we do if the recursive call works correctly?
- We've read one number. We've summed all the remaining numbers.
So ... just add 'em together.
- Okay, now we're ready to worry about some details.
- We don't read from files, we read from ports. Hence, we'll add
a husk that converts the file name to a port.
- See the reading for more
- We'll also add some error checking.
- You can read a character at a time (rather than a value at a time) using
- Why is this useful? It lets you be more general than the
- You can also look at the next character that you're about to read
- Why is this useful? Sometimes you want to read differently based on
what you see next.
- If you see a semicolon, read the whole line as a string and ignore it.
- If you see anything else, read it as a Scheme value
read-char encounters the end of the file, it returns
the same special value as
- Let's consider an example in which we read a line of text from a file.
- See the reading for more details.
Thursday, 28 August 2003 [Samuel A. Rebelsky]