title: fgets implementation from the std library of K&R 2nd edition
body: <p>I'm aware that code snippets from textbooks are just for demonstration purposes and shouldn't be held to production standards but K&amp;R 2nd edition on page 164-165 says:</p>
  <blockquote>
  <p><code>fgets</code> and <code>fputs</code>, here they are, copied from the standard library
  on our system:</p>
  </blockquote>
  <pre><code>char *fgets(char *s, int n, FILE *iop)
  {
      register int c;
      register char *cs;
      
      cs = s;
      while (--n &gt; 0 &amp;&amp; (c = getc(iop)) != EOF)
          if ((*cs++ = c) == '\n')
              break;
      *cs = '\0';
      return (c == EOF &amp;&amp; cs == s) ? NULL : s;
  }
  </code></pre>
  <p>Why is the <code>return</code> statement not <code>return (ferror(iop) || (c == EOF &amp;&amp; cs == s)) ? NULL : s;</code> since:</p>
  <ol>
  <li><a href="http://port70.net/%7Ensz/c/c89/c89-draft.html#4.9.7.2" rel="nofollow noreferrer">ANSI C89 standard</a> says:</li>
  </ol>
  <blockquote>
  <p>If a read <strong>error</strong> occurs during the operation, the array contents are
  indeterminate and a null pointer is returned.</p>
  </blockquote>
  <ol start="2">
  <li>Even the standard library illustrated in Appendix B of the book says so. From Page 247:</li>
  </ol>
  <blockquote>
  <p><code>fgets</code> returns <code>s</code>, or <code>NULL</code> if end of file or <strong>error</strong> occurs.</p>
  </blockquote>
  <ol start="3">
  <li>K&amp;R uses <code>ferror(iop)</code> in <code>fputs</code> implementation given just below this <code>fgets</code> implementation on the same page.</li>
  </ol>
  <p>With the above implementation, <code>fgets</code> will return <code>s</code> even if there is a read <strong>error</strong> after reading some characters. Maybe this is an oversight or am I missing something?</p>