* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes.int / sx2h.html
blobbf0153fc9802fb474dd5582dd2f20f10f6a2e757
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
5 <html>
6 <head>
7 <link rev="owner" href="mailto:scs@eskimo.com">
8 <link rev="made" href="mailto:scs@eskimo.com">
9 <title>16.8: <TT>EOF</TT> and Errors</title>
10 <link href="sx2g.html" rev=precedes>
11 <link href="sx2i.html" rel=precedes>
12 <link href="sx2.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>16.8: <TT>EOF</TT> and Errors</H2>
17 <p>When a function returns <TT>EOF</TT>
18 (or, occasionally, 0 or <TT>NULL</TT>,
19 as in the case of <TT>fread</TT> and <TT>fgets</TT> respectively),
20 we commonly say that we have reached ``end of file,''
21 but it turns out that it's also possible
22 that there's been some kind of I/O error.
23 When you want to distinguish between end-of-file and error,
24 you can do so with the <TT>feof</TT> and <TT>ferror</TT> functions.
25 <TT>feof(fp)</TT> returns nonzero
26 (that is, ``true'')
27 if end-of-file has been reached on the stream <TT>fp</TT>,
28 and <TT>ferror(fp)</TT> returns nonzero
29 if there has been an error.
30 Notice the past tense and passive voice:
31 <TT>feof</TT> returns nonzero if end-of-file
32 <em>has been reached</em>.
33 It does <em>not</em> tell you that the next attempt to read from
34 the stream will reach end-of-file,
35 but rather that the previous attempt
36 (by some other function)
37 already <em>did</em>.
38 (If you know Pascal,
39 you may notice that the end-of-file detection situation in C
40 is therefore
41 quite different from Pascal.)
42 Therefore, you would never write a loop like
43 <pre>
44 while(!feof(fp))
45 fgets(line, max, fp);
46 </pre>
47 Instead, check the return value of the input function directly:
48 <pre>
49 while(fgets(line, max, fp) != NULL)
50 </pre>
51 With a very few possible exceptions, you don't use <TT>feof</TT>
52 to <em>detect</em> end-of-file;
53 you use <TT>feof</TT> or <TT>ferror</TT> to distinguish
54 between end-of-file and error.
55 (You can also use <TT>ferror</TT> to diagnose error conditions on
56 output files.)
57 </p><p>Since the end-of-file and error conditions tend to persist on a stream,
58 it's sometimes necessary to clear (reset) them,
59 which you can do with <TT>clearerr(FILE *fp)</TT>.
60 </p><p>What should your program do if it detects an I/O error?
61 Certainly, it cannot continue as usual;
62 usually, it will print an error message.
63 The simplest error messages are of the form
64 <pre>
65 fp = fopen(filename, "r");
66 if(fp == NULL)
68 fprintf(stderr, "can't open file\n");
69 return;
71 </pre>
73 <pre>
74 while(fgets(line, max, fp) != NULL)
76 <I>... process input ...</I>
79 if(ferror(fp))
80 fprintf(stderr, "error reading input\n");
81 </pre>
83 <pre>
84 fprintf(ofp, "%d %d %d\n", a, b, c);
85 if(ferror(ofp))
86 fprintf(stderr, "output write error\n");
87 </pre>
88 Error messages are much more useful,
89 however,
90 if they include a bit more information,
91 such as the name of the file for which the operation is failing,
92 and if possible <em>why</em> it is failing.
93 For example,
94 here is a more polite way to report that a file could not be opened:
95 <pre>
96 #include &lt;stdio.h&gt; /* for fopen */
97 #include &lt;errno.h&gt; /* for errno */
98 #include &lt;string.h&gt; /* for strerror */
100 fp = fopen(filename, "r");
101 if(fp == NULL)
103 fprintf(stderr, "can't open %s for reading: %s\n",
104 filename, strerror(errno));
105 return;
107 </pre>
108 <TT>errno</TT> is a global variable, declared in <TT>&lt;errno.h&gt;</TT>,
109 which may
111 contain
112 a numeric code
113 indicating the reason for a recent system-related error
114 such as inability to open a file.
115 The <TT>strerror</TT> function takes an <TT>errno</TT> code
116 and returns a human-readable string
117 such as ``No such file'' or ``Permission denied''.
118 </p><p>An even more useful error message,
119 especially for a ``toolkit'' program
120 intended to be used in conjunction with other programs,
121 would include in the message text
122 the name of the program reporting the error.
123 </p><hr>
125 Read sequentially:
126 <a href="sx2g.html" rev=precedes>prev</a>
127 <a href="sx2i.html" rel=precedes>next</a>
128 <a href="sx2.html" rev=subdocument>up</a>
129 <a href="top.html">top</a>
130 </p>
132 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
133 // <a href="copyright.html">Copyright</a> 1996-1999
134 // <a href="mailto:scs@eskimo.com">mail feedback</a>
135 </p>
136 </body>
137 </html>