PageRenderTime 23ms CodeModel.GetById 14ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/share/doc/psd/04.uprog/p3

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