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