|
|
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.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.