Annotation of 43BSDReno/share/doc/ps2/03.uprog/p3, revision 1.1.1.1

1.1       root        1: .\"    @(#)p3  6.3 (Berkeley) 5/10/86
                      2: .\"
                      3: .NH
                      4: THE STANDARD I/O LIBRARY
                      5: .PP
                      6: The ``Standard I/O Library''
                      7: is a collection of routines
                      8: intended to provide
                      9: efficient
                     10: and portable
                     11: I/O services
                     12: for most C programs.
                     13: The standard I/O library is available on each system that supports C,
                     14: so programs that confine
                     15: their system interactions
                     16: to its facilities
                     17: can be transported from one system to another essentially without change.
                     18: .PP
                     19: In this section, we will discuss the basics of the standard I/O library.
                     20: The appendix contains a more complete description of its capabilities.
                     21: .NH 2
                     22: File Access
                     23: .PP
                     24: The programs written so far have all
                     25: read the standard input and written the standard output,
                     26: which we have assumed are magically pre-defined.
                     27: The next step
                     28: is to write a program that accesses
                     29: a file that is
                     30: .ul
                     31: not
                     32: already connected to the program.
                     33: One simple example is
                     34: .IT wc ,
                     35: which counts the lines, words and characters
                     36: in a set of files.
                     37: For instance, the command
                     38: .P1
                     39: wc x.c y.c
                     40: .P2
                     41: prints the number of lines, words and characters
                     42: in
                     43: .UL x.c
                     44: and
                     45: .UL y.c
                     46: and the totals.
                     47: .PP
                     48: The question is how to arrange for the named files
                     49: to be read \(em
                     50: that is, how to connect the file system names 
                     51: to the I/O statements which actually read the data.
                     52: .PP
                     53: The rules are simple.
                     54: Before it can be read or written
                     55: a file has to be
                     56: .ul
                     57: opened
                     58: by the standard library function
                     59: .UL fopen .
                     60: .UL fopen
                     61: takes an external name
                     62: (like
                     63: .UL x.c
                     64: or
                     65: .UL y.c ),
                     66: does some housekeeping and negotiation with the operating system,
                     67: and returns an internal name
                     68: which must be used in subsequent
                     69: reads or writes of the file.
                     70: .PP
                     71: This internal name is actually a pointer,
                     72: called a
                     73: .IT file
                     74: .IT pointer ,
                     75: to a structure
                     76: which contains information about the file,
                     77: such as the location of a buffer,
                     78: the current character position in the buffer,
                     79: whether the file is being read or written,
                     80: and the like.
                     81: Users don't need to know the details,
                     82: because part of the standard I/O definitions
                     83: obtained by including
                     84: .UL stdio.h
                     85: is a structure definition called
                     86: .UL FILE .
                     87: The only declaration needed for a file pointer
                     88: is exemplified by
                     89: .P1
                     90: FILE   *fp, *fopen();
                     91: .P2
                     92: This says that
                     93: .UL fp
                     94: is a pointer to a
                     95: .UL FILE ,
                     96: and
                     97: .UL fopen
                     98: returns a pointer to
                     99: a
                    100: .UL FILE .
                    101: .UL FILE \& (
                    102: is a type name, like
                    103: .UL int ,
                    104: not a structure tag.
                    105: .PP
                    106: The actual call to
                    107: .UL fopen
                    108: in a program
                    109: is
                    110: .P1
                    111: fp = fopen(name, mode);
                    112: .P2
                    113: The first argument of
                    114: .UL fopen
                    115: is the
                    116: name
                    117: of the file,
                    118: as a character string.
                    119: The second argument is the
                    120: mode,
                    121: also as a character string,
                    122: which indicates how you intend to
                    123: use the file.
                    124: The only allowable modes are
                    125: read
                    126: .UL \&"r" ), (
                    127: write
                    128: .UL \&"w" ), (
                    129: or append
                    130: .UL \&"a" ). (
                    131: .PP
                    132: If a file that you open for writing or appending does not exist,
                    133: it is created
                    134: (if possible).
                    135: Opening an existing file for writing causes the old contents
                    136: to be discarded.
                    137: Trying to read a file that does not exist
                    138: is an error,
                    139: and there may be other causes of error
                    140: as well
                    141: (like trying to read a file
                    142: when you don't have permission).
                    143: If there is any error,
                    144: .UL fopen
                    145: will return the null pointer
                    146: value
                    147: .UL NULL 
                    148: (which is defined as zero in
                    149: .UL stdio.h ).
                    150: .PP
                    151: The next thing needed is a way to read or write the file
                    152: once it is open.
                    153: There are several possibilities,
                    154: of which
                    155: .UL getc
                    156: and
                    157: .UL putc
                    158: are the simplest.
                    159: .UL getc
                    160: returns the next character from a file;
                    161: it needs the file pointer to tell it what file.
                    162: Thus
                    163: .P1
                    164: c = getc(fp)
                    165: .P2
                    166: places in 
                    167: .UL c
                    168: the next character from the file referred to by
                    169: .UL fp ;
                    170: it returns
                    171: .UL EOF
                    172: when it reaches end of file.
                    173: .UL putc
                    174: is the inverse of
                    175: .UL getc :
                    176: .P1
                    177: putc(c, fp)
                    178: .P2
                    179: puts the character
                    180: .UL c
                    181: on the file
                    182: .UL fp 
                    183: and returns
                    184: .UL c .
                    185: .UL getc
                    186: and
                    187: .UL putc
                    188: return
                    189: .UL EOF
                    190: on error.
                    191: .PP
                    192: When a program is started, three files are opened automatically,
                    193: and file pointers are provided for them.
                    194: These files are the standard input,
                    195: the standard output,
                    196: and the standard error output;
                    197: the corresponding file pointers are
                    198: called
                    199: .UL stdin ,
                    200: .UL stdout ,
                    201: and
                    202: .UL stderr .
                    203: Normally these are all connected to the terminal,
                    204: but
                    205: may be redirected to files or pipes as described in
                    206: Section 2.2.
                    207: .UL stdin ,
                    208: .UL stdout
                    209: and
                    210: .UL stderr
                    211: are pre-defined in the I/O library
                    212: as the standard input, output and error files;
                    213: they may be used anywhere an object of type
                    214: .UL FILE\ *
                    215: can be.
                    216: They are 
                    217: constants, however,
                    218: .ul
                    219: not
                    220: variables,
                    221: so don't try to assign to them.
                    222: .PP
                    223: With some of the preliminaries out of the way,
                    224: we can now write
                    225: .IT wc .
                    226: The basic design 
                    227: is one that has been found
                    228: convenient for many programs:
                    229: if there are command-line arguments, they are processed in order.
                    230: If there are no arguments, the standard input
                    231: is processed.
                    232: This way the program can be used stand-alone
                    233: or as part of a larger process.
                    234: .P1
                    235: #include <stdio.h>
                    236: 
                    237: main(argc, argv)       /* wc: count lines, words, chars */
                    238: int argc;
                    239: char *argv[];
                    240: {
                    241:        int c, i, inword;
                    242:        FILE *fp, *fopen();
                    243:        long linect, wordct, charct;
                    244:        long tlinect = 0, twordct = 0, tcharct = 0;
                    245: 
                    246:        i = 1;
                    247:        fp = stdin;
                    248:        do {
                    249:                if (argc > 1 && (fp=fopen(argv[i], "r")) == NULL) {
                    250:                        fprintf(stderr, "wc: can't open %s\en", argv[i]);
                    251:                        continue;
                    252:                }
                    253:                linect = wordct = charct = inword = 0;
                    254:                while ((c = getc(fp)) != EOF) {
                    255:                        charct++;
                    256:                        if (c == '\en')
                    257:                                linect++;
                    258:                        if (c == ' ' || c == '\et' || c == '\en')
                    259:                                inword = 0;
                    260:                        else if (inword == 0) {
                    261:                                inword = 1;
                    262:                                wordct++;
                    263:                        }
                    264:                }
                    265:                printf("%7ld %7ld %7ld", linect, wordct, charct);
                    266:                printf(argc > 1 ? " %s\en" : "\en", argv[i]);
                    267:                fclose(fp);
                    268:                tlinect += linect;
                    269:                twordct += wordct;
                    270:                tcharct += charct;
                    271:        } while (++i < argc);
                    272:        if (argc > 2)
                    273:                printf("%7ld %7ld %7ld total\en", tlinect, twordct, tcharct);
                    274:        exit(0);
                    275: }
                    276: .P2
                    277: The function
                    278: .UL fprintf
                    279: is identical to
                    280: .UL printf ,
                    281: save that the first argument is a file pointer
                    282: that specifies the file to be
                    283: written.
                    284: .PP
                    285: The function
                    286: .UL fclose
                    287: is the inverse of
                    288: .UL fopen ;
                    289: it breaks the connection between the file pointer and the external name
                    290: that was established by
                    291: .UL fopen ,
                    292: freeing the
                    293: file pointer for another file.
                    294: Since there is a limit on the number
                    295: of files
                    296: that a program may have open simultaneously,
                    297: it's a good idea to free things when they are no longer needed.
                    298: There is also another reason to call
                    299: .UL fclose 
                    300: on an output file
                    301: \(em it flushes the buffer
                    302: in which
                    303: .UL putc
                    304: is collecting output.
                    305: .UL fclose \& (
                    306: is called automatically for each open file
                    307: when a program terminates normally.)
                    308: .NH 2
                    309: Error Handling \(em Stderr and Exit
                    310: .PP
                    311: .UL stderr
                    312: is assigned to a program in the same way that
                    313: .UL stdin
                    314: and
                    315: .UL stdout
                    316: are.
                    317: Output written on 
                    318: .UL stderr
                    319: appears on the user's terminal
                    320: even if the standard output is redirected.
                    321: .IT wc
                    322: writes its diagnostics on
                    323: .UL stderr
                    324: instead of
                    325: .UL stdout
                    326: so that if one of the files can't
                    327: be accessed for some reason,
                    328: the message
                    329: finds its way to the user's terminal instead of disappearing
                    330: down a pipeline
                    331: or into an output file.
                    332: .PP
                    333: The program actually signals errors in another way,
                    334: using the function
                    335: .UL exit 
                    336: to terminate program execution.
                    337: The argument of
                    338: .UL exit
                    339: is available to whatever process
                    340: called it (see Section 6),
                    341: so the success or failure
                    342: of the program can be tested by another program
                    343: that uses this one as a sub-process.
                    344: By convention, a return value of 0
                    345: signals that all is well;
                    346: non-zero values signal abnormal situations.
                    347: .PP
                    348: .UL exit
                    349: itself
                    350: calls
                    351: .UL fclose
                    352: for each open output file,
                    353: to flush out any buffered output,
                    354: then calls
                    355: a routine named
                    356: .UL _exit .
                    357: The function
                    358: .UL _exit
                    359: causes immediate termination without any buffer flushing;
                    360: it may be called directly if desired.
                    361: .NH 2
                    362: Miscellaneous I/O Functions
                    363: .PP
                    364: The standard I/O library provides several other I/O functions
                    365: besides those we have illustrated above.
                    366: .PP
                    367: Normally output with
                    368: .UL putc ,
                    369: etc., is buffered (except to
                    370: .UL stderr );
                    371: to force it out immediately, use
                    372: .UL fflush(fp) .
                    373: .PP
                    374: .UL fscanf
                    375: is identical to
                    376: .UL scanf ,
                    377: except that its first argument is a file pointer
                    378: (as with
                    379: .UL fprintf )
                    380: that specifies the file from which the input comes;
                    381: it returns
                    382: .UL EOF
                    383: at end of file.
                    384: .PP
                    385: The functions
                    386: .UL sscanf
                    387: and
                    388: .UL sprintf
                    389: are identical to
                    390: .UL fscanf
                    391: and
                    392: .UL fprintf ,
                    393: except that the first argument names a character string
                    394: instead of a file pointer.
                    395: The conversion is done from the string
                    396: for 
                    397: .UL sscanf 
                    398: and into it for
                    399: .UL sprintf .
                    400: .PP
                    401: .UL fgets(buf,\ size,\ fp)
                    402: copies the next line from
                    403: .UL fp ,
                    404: up to and including a newline,
                    405: into 
                    406: .UL buf ;
                    407: at most
                    408: .UL size-1
                    409: characters are copied;
                    410: it returns
                    411: .UL NULL
                    412: at end of file.
                    413: .UL fputs(buf,\ fp)
                    414: writes the string in
                    415: .UL buf
                    416: onto file
                    417: .UL fp .
                    418: .PP
                    419: The function
                    420: .UL ungetc(c,\ fp)
                    421: ``pushes back'' the character
                    422: .UL c
                    423: onto the input stream
                    424: .UL fp ;
                    425: a subsequent call to
                    426: .UL getc ,
                    427: .UL fscanf ,
                    428: etc.,
                    429: will encounter 
                    430: .UL c .
                    431: Only one character of pushback per file is permitted.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.