Annotation of 43BSDReno/share/doc/ps2/03.uprog/p3, revision 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.