Many times it is useful to report errors in a C program. The standard library
perror() is an easy to use and convenient function. It is used in
conjunction with errno and frequently on encountering an error you may
wish to terminate your program early. Whilst not strictly part of the
stdio.h library we introduce the concept of errno and the function
exit() here. We will meet these concepts in other parts of the Standard
Library also.

perror() produces a message (on standard error output -- see
Section 17.2.1), describing the last error encountered, returned
to errno (see below)
during a call to a system or library function. The argument
string message is printed first, then a colon and a blank, then
the message and a newline. If message is a NULL pointer
or points to a null string, the colon is not printed.

Streams are a portable way of reading and writing data. They provide a
flexible and efficient means of I/O.

A Stream is a file or a physical device (e.g. printer or
monitor) which is manipulated with a pointer to the stream.

There exists an internal C data structure, FILE, which represents all
streams and is defined in stdio.h. We simply need to refer to the
FILE structure in C programs when performing I/O with streams.

We just need to declare a variable or pointer of this type in our
programs.

We do not need to know any more specifics about this definition.

We must open a stream before doing any I/O,

then access it

and then close it.

Stream I/O is BUFFERED: That is to say a fixed "chunk" is read from or
written to a file via some temporary storage area (the buffer). This is
illustrated in Fig. 17.1. NOTE the file pointer actually points to
this buffer.

Fig. Stream I/O Model
This leads to efficient I/O but beware: data written to a buffer does not
appear in a file (or device) until the buffer is flushed or written out.
(n does this). Any abnormal exit of code can cause problems.

The first thing we must do is open a file. The function fopen()
does this:

FILE *fopen(char *name, char *mode)

fopen returns a pointer to a FILE. The name string is the name of
the file on disc that we wish to access. The mode string controls our
type of access. If a file cannot be accessed for any reason a NULL
pointer is returned.

Modes include: "r" -- read,
"w" -- write and
"a" -- append.

To open a file we must have a stream (file pointer) that points to a
FILE structure.

Write a program to copy one named file into another named file. The two file
names are given as the first two arguments to the program.

Copy the file a block (512 bytes) at a time.

Check: that the program has two arguments
or print "Program need two arguments"
that the first name file is readable
or print "Cannot open file .... for reading"
that the second file is writable
or print "Cannot open file .... for writing"

Exercise 12577

Write a program last that prints the last n lines of a text file, by n and
the file name should be specified form command line input. By default n should
be 5, but your program should allow an optional argument so that

last -n file.txt

prints out the last n lines, where n is any integer. Your program should make
the best use of available storage.

Exercise 12578

Write a program to compare two files and print out the lines where they
differ. Hint: look up appropriate string and file handling library routines.
This should not be a very long program.