www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/05/11/06:13:01

From: buers AT gmx DOT de (Dieter Buerssner)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: feof(FILE *) NOT portable...
Date: 11 May 2000 10:09:20 GMT
Lines: 89
Message-ID: <8fe6jv.3vvrbov.0@buerssner-17104.user.cis.dfn.de>
References: <8empao$5k6$1 AT nnrp02 DOT primenet DOT com> <390ef9f9$0$72098 AT SSP1NO17 DOT highway DOT telekom DOT at> <8emvhq$7mn$1 AT nnrp03 DOT primenet DOT com> <3 DOT 0 DOT 6 DOT 32 DOT 20000505015633 DOT 007b2210 AT pop DOT crosswinds DOT net> <3 DOT 0 DOT 6 DOT 32 DOT 20000510204858 DOT 007b6e40 AT pop DOT crosswinds DOT net>
NNTP-Posting-Host: pec-3-213.tnt2.s2.uunet.de (149.225.3.213)
Mime-Version: 1.0
X-Trace: fu-berlin.de 958039760 11037935 149.225.3.213 (16 [17104])
X-Posting-Agent: Hamster/1.3.13.0
User-Agent: Xnews/03.02.04
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Thomas J. Hruska wrote:

>char *LineInput(FILE *fp)
>{
>  char *str, x[2];
>  str = (char *)malloc(1);
>  str[0] = '\0';
>  if (feof(fp))  return str;
>  x[1] = '\0';
>  do
>  {
>    x[0] = fgetc(fp);
>    str = (char *)realloc(str, strlen(str) + 2);
>    strcat(str, x);
>  } while (!feof(fp) && x[0] != 10);
>  if (x[0] != 10)  return str;
>  str[strlen(str) - 2] = '\0';
>  str = (char *)realloc(str, strlen(str) + 1);
>  return str;
>}
>
>Under any other compiler besides DJGPP, this works fine.  Under DJGPP, the
>last line of ANY file will have an extra character on the end. 

DJGPP seems correct from your description. From the comp.lang.c FAQ

12.2:   Why does the code

                while(!feof(infp)) {
                        fgets(buf, MAXLINE, infp);
                        fputs(buf, outfp);
                }

        copy the last line twice?

A:      In C, end-of-file is only indicated *after* an input routine has
        tried to read, and failed.  (In other words, C's I/O is not like
        Pascal's.)  Usually, you should just check the return value of
        the input routine (in this case, fgets() will return NULL on end-
        of-file); often, you don't need to use feof() at all.

Also, I get the same behaviour with bcc 5.5 (and remember the same
behaviour back in Turbo-C 2.0).

> I do NOT
>relish the idea of modifying this ancient code (wrote it in early 1997) to
>include one more realloc. 

It does already contain too many realloc calls, none of which tests
for NULL return. It uses unneeded calls to strlen and strcat. IHMO,
you should change your code.

#include <stdlib.h>
#include <stdio.h>

/* Untested, supplement with checking the return of malloc/realloc */
/* A different interface, that indicates EOF back to the caller, could
   be more useful. */
char *LineInput(FILE *fp)
{
  size_t nread, nalloc;
  int c;
  char *bp;
  nalloc = 16;
  nread = 0;
  bp = malloc(nalloc);
  while (1)
  {
    c = fgetc(fp);
    if (c == EOF || c == '\n')
      break;
    bp[nread++] = c;
    if (nread >= nalloc)
    {
      nalloc *= 2;
      bp = realloc(bp, nalloc);
    }
  }
  bp[nread] = '\0';
  bp = realloc(bp, nread);
  return bp;
}

> Make sure the next release of DJGPP fixes this bug.

From your description, I don't see anything that has to be fixed.

-- 
Dieter Buerssner

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019