CS50 File I/O Review Notes
Like command line arguments, file I/O is very important to ``real''
programs; even though we haven't done all that much with file I/O in
this course, if you're planning on doing more programming, you're
going to see this stuff again.
This subject is covered somewhat in the Roberts book, but much
more throughly in K+R and the online manual pages.
The Standard I/O library (stdio) provides
C programmers with a number of useful functions
and abstractions for dealing with raw files.
The abstraction of files provided by the standard I/O
library (stdio) is implemented in a structure called
FILE. Almost all of the stdio functions take a pointer
to one of these structures as one of their parameters
(either explicitly or implicitly). The main exception
is fopen, which is used to get one of these
pointers in the first place.
UNIX gives your programs three default FILE pointers,
just for showing up:
- stdin - standard input. For interactive
programs, if you read standard input, you'll get
what the user types on the keyboard.
- stdout - standard output. For interactive
programs, if you write to standard output, then
whatever you write will appear on the users screen.
- stderr - standard error. Like stdout, but
can be treated seperately when appropriate. For example, if you want
to capture all of the error messages that your program
emits, you can redirect stderr to a file and still have
all the ordinary (stdout) message show up on your screen-
or vice versa.
Here is list of some of the more popular functions:
- fopen and fclose
- Open or close a file.
- fgetc and fputc
- Read or write a single character.
An important note about fgetc (that pops
up in a few other places): although fgetc reads
a char, it returns an int. This
is esential for the following reason- if fgetc
just returned a char, then what value could it return
to indicate to you that something had gone wrong?
Every possible return value (any member of
the set of possible chars) would correspond to something
that might actually be in a file. Therefore, in order
to make it possible to also return error codes, fgetc
returns an int. If the value is 0..255 (for 8-bit chars)
then you know that fgetc succeeded, but if
it is outside this range, then something else happened.
For most implementations of fgetc that I am aware
of, there's only one error code, which is EOF (which is
returned when you attempt to read past the end of the file, or
some other error occurs), other functions use a similar
philosophy and return different things.
Note that there are several related functions and macros:
getchar, getc, putchar, and putc. These can be useful,
and you'll see them a lot (particularly in older code)
but fgetc and fputc are all you need.
- fgets and fputs
- Read or write a line of text. Assumes that the file is
text. (Note- fputs does not add a newline, so if
you want there to be one, you must add it yourself)
There is another function named gets which is
similar to fgets, but notoriously dangerous to use.
(It doesn't check its arguments, nor does it check that what
the user types is valid, and so can permit the user to
scribble all over memory.) I suggest that you never use it.
- fread and fwrite
- Read or write "blocks" of data. Useful for reading or writing an
entire array or structure, or any arbitrary (but specific)
amount of data.
- fscanf and fprintf
- Read or write data according to given format. fprintf
is almost exactly like printf, but prints to a file
instead of the screen.
fscanf is sort of like fprintf, only
backwards. It can be tricky to use; one simplification to
help do formatted reading is to use fgets to read a
line of text and then use sscanf (a relative of
fscanf that scans strings instead of files) instead
of using fscanf.
- fseek and ftell
- Move around in a file, or find out where you are in a file.
The rewind function is a special case of the
fseek that can be used to rewind to the beginning
of a file. (Note that some files can't be rewound- you'd need
a time machine to rewind stdin, for example!)
- Flush changes (make them happen immediately).
- feof and ferror
- Determine if the End Of File has been reached, or some
All the functions in the stdio library are built on top of
UNIX's unformatted I/O functions.
- open and close open or close a file.
- read and write read or write unformatted data.
- lseek move around in a file.
- ioctl I/O control. A weird utility function that does
lots of different things, depending on its arguments.
Generally used for low-level manipulation of an object that
UNIX treats like a file, but actually is something else (i.e.
your terminal- you can read from stdin and write
to stdout as if they are files, but there are also
other things that you can do to them).
- dup and dup2 duplicate a file descriptor.
Please bring any errors or inconsistencies in this document
to the attention of the author.
Dan Ellard - (firstname.lastname@example.org)