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