|
|
The functions in Subsection 3S constitute the standard I/O library for C programs. I/O involves:
Programs automatically start off with three open files: standard input, standard output, and standard error. These files with their associated buffering are designated stdin, stdout, and stderr, respectively. The shell associates all three files with your terminal by default.
You can use functions and macros that deal with stdin, stdout, or stderr without having to open or close files. gets, for example, reads a string from stdin; puts writes a string to stdout. Other functions and macros read from or write to files in different ways: character at a time, getc and putc; formatted, scanf and printf; and so on. You can specify that output be directed to stderr by using a function such as fprintf. fprintf works the same way as printf except that it delivers its formatted output to a named stream, such as stderr.
Any file other than standard input, standard output, and standard error must be explicitly opened before your program can read from or write to the file. You open a file with the standard library function fopen. fopen takes a path name, asks the system to keep track of the connection between your program and the file, and returns a pointer that you can then use in functions that perform other I/O operations. This bookkeeping mechanism associated with a file is referred to as a stdio stream.
The data structure associated with a stream, FILE
, is defined in
stdio.h.
The FILE
structure members are intended for use only by the
stdio subsystem.
For example,
your program must have a declaration such as
FILE fin;which says that
fin
is a pointer to a FILE
.
The statement
associates a structure of type FILE
with filename,
the path name of the file to open, and returns a pointer to it.
The ``"r"'' means that the file is to be opened for reading.
This argument is known as the mode.
There are modes for reading, writing, and
both reading and writing.
In practice, the file open function is often included in an if statement:
if ((fin = fopen("filename", "r")) == NULL) (void)fprintf(stderr,"Cannot open input file %s\n", "filename");which uses fopen to return a NULL pointer if it cannot open the file. To avoid falling into the immediately following code on failure, you can call exit, which causes your program to quit:
if ((fin = fopen("filename", "r")) == NULL) { (void)fprintf(stderr,"Cannot open input file %s\n", "filename"); exit(1); }Once you have opened the file, you use the pointer
fin
in functions or macros
to refer to the stream associated with the opened file:
int c; c = getc(fin);brings in one character from the stream into an integer variable called c. The variable c is declared as an integer even though it is reading characters because getc returns an integer. Getting a character is often incorporated in some flow-of-control mechanism such as
while ((c = getc(fin)) != EOF) . . .that reads through the file until EOF is returned. EOF, NULL, and the macro getc are all defined in stdio.h.
Your program may have multiple files open simultaneously, 20 or more depending on system configuration. If your program needs to open more files than it is permitted to have open simultaneously, you can use the standard library function fclose to free up a stdio stream for reuse by your program. fclose first flushes the output buffer for write streams and frees any memory allocated by the stdio subsystem associated with the stream. The stdio stream is then available for reuse. exit closes all open files for you, but it also gets you completely out of your process, so you should use it only when you are sure you are finished.
As indicated in ``Introduction to programming in standard C and C++'', information or control data can be passed to a C program as an argument on the command line. When you execute the program, command line arguments are made available to the function main in two parameters, an argument count, conventionally called argc, and an argument vector, conventionally called argv. argc is the number of arguments with which the program was invoked. argv is an array of pointers to characters strings that contain the arguments, one per string. Because the command name itself is considered to be the first argument, or argv[0], the count is always at least one.
If you plan to accept run-time parameters in your program, you need to include code to deal with the information.
``Using argv[1] to Pass a File Name'' and ``Using Command Line Arguments to Set Flags'' show program fragments that illustrate two common uses of run-time parameters:
``Using argv[1] to Pass a File Name''
shows how you provide a variable file name to a program,
such that a command of the form
$ prog filename
will cause prog to attempt to open the specified file.
``Using Command Line Arguments to Set Flags''
shows how you set internal flags that
control the operation of a program,
such that a command of the form
$ prog -opr
will cause prog to set the corresponding variables for each of the options specified. The getopt function used in the example is the most common way to process arguments in UNIX® operating system programs. See getopt(3C) for more information.
#include <stdio.h>int main(int argc, char argv[]) { FILE fin; int ch;
switch (argc) { case 2: if ((fin = fopen(argv[1], "r")) == NULL) { / First string (%s) is program name (argv[0]). / / Second string (%s) is name of file that could / / not be opened (argv[1]). /
(void)fprintf(stderr, "%s: Cannot open input file %s\n", argv[0], argv[1]); return(2); } break; case 1: fin = stdin; break;
default: (void)fprintf(stderr, "Usage: %s [file]\n", argv[0]); return(2); }
while ((ch = getc(fin)) != EOF) (void)putchar(ch);
return (0);
}
Using argv[1] to Pass a File Name
#include <stdio.h> #include <stdlib.h>int main(int argc, char argv[]) { int oflag = 0; int pflag = 0; / Function flags / int rflag = 0; int ch;
while ((ch = getopt(argc, argv, "opr")) != -1) { / For options present, set flag to 1. / / If unknown options present, print error message. /
switch (ch) { case 'o': oflag = 1; break; case 'p': pflag = 1; break; case 'r': rflag = 1; break; default: (void)fprintf(stderr, "Usage: %s [-opr]\n", argv[0]); return(2); } } / Do other processing controlled by oflag, pflag, rflag. / return(0); }
Using Command Line Arguments to Set Flags