Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

fgetln

191 views
Skip to first unread message

ian.c...@gmail.com

unread,
Jul 2, 2008, 3:32:02 PM7/2/08
to
Sorry if this is old hat, but I haven't posted here for a decade or
two....

Does anyone know why the BSD (and hence Mac OS X) fgetln() function
didn't make it into C99? Is it being considered for a future revision
of the standard?

Kind regards
-Ian Cottam

Jonathan Leffler

unread,
Jul 4, 2008, 12:59:09 AM7/4/08
to

At a first guess, no-one proposed it as an addition and shepherded it
into the standard.

At a second guess, after Googling 'fgetln', they did not think it well
designed. One comment visible notes "The fgetln() function returns a
pointer to the next line from the specified stream. This line is not a C
string as it does not end with a terminating null [...]".

The OpenBSD manual page for fgetln() makes it clear that the returned
pointer readily becomes invalid:

Upon successful completion a pointer is returned; this pointer becomes
invalid after the next I/O operation on stream (whether successful or
not) or as soon as the stream is closed. Otherwise, NULL is returned.

Explain to us why we would want the abomination that is gets() replaced
by fgetln()?

--
Jonathan Leffler #include <disclaimer.h>
Email: jlef...@earthlink.net, jlef...@us.ibm.com
Guardian of DBD::Informix v2008.0229 -- http://dbi.perl.org/

publictimestamp.org/ptb/PTB-3645 tiger2 2008-07-04 03:00:06
784E36A3C2E87E55F53C0D1BFBB34CE06D88C9D9D83E90CB

ian.c...@gmail.com

unread,
Jul 4, 2008, 2:34:02 PM7/4/08
to
On Jul 4, 5:59 am, Jonathan Leffler <jleff...@earthlink.net> wrote:

> ian.cot...@gmail.com wrote:
> > Sorry if this is old hat, but I haven't posted here for a decade or
> > two....
>
> > Does anyone know why the BSD (and hence Mac OS X)fgetln() function

> > didn't make it into C99? Is it being considered for a future revision
> > of the standard?
>
> At a first guess, no-one proposed it as an addition and shepherded it
> into the standard.
>
> At a second guess, after Googling 'fgetln', they did not think it well
> designed. One comment visible notes "Thefgetln() function returns a

> pointer to the next line from the specified stream. This line is not a C
> string as it does not end with a terminating null [...]".
>
> The OpenBSD manual page forfgetln() makes it clear that the returned

> pointer readily becomes invalid:
>
> Upon successful completion a pointer is returned; this pointer becomes
> invalid after the next I/O operation on stream (whether successful or
> not) or as soon as the stream is closed. Otherwise, NULL is returned.
>
> Explain to us why we would want the abomination that is gets() replaced
> byfgetln()?
>
> --
> Jonathan Leffler #include <disclaimer.h>
> Email: jleff...@earthlink.net, jleff...@us.ibm.com
> Guardian of DBD::Informix v2008.0229 --http://dbi.perl.org/

>
> publictimestamp.org/ptb/PTB-3645 tiger2 2008-07-04 03:00:06
> 784E36A3C2E87E55F53C0D1BFBB34CE06D88C9D9D83E90CB

It enables a very simple fgetline() to be written; see below.
-Ian
/*
* returns a pointer to the start of a line read
* from f, or the null pointer on any error or eof.
* Like fgets(), you may well want to get rid of the
* \n at the end (if any), and check feof(f)! This is
* not a wonderful interface, but it mimics fgets().
* Caller should free memory.
*/
#ifdef FGETLN
/* May well be the case that only BSD based systems (including Mac OS
X) have fgetln() */

static char *fgetline(FILE *f)
{
size_t len;
char *line= fgetln(f, &len);
if (line == 0) return 0;
char *buf= malloc(len+1);
if (buf == 0) return 0;
memcpy(buf, line, len);
buf[len]= '\0';
return buf;
}


#endif

#ifndef FGETLN
# define FGETLINE_BUFFSIZE 256
static char *fgetline(FILE *f)
{
int ch;
size_t length= 0;
size_t buffer_length= FGETLINE_BUFFSIZE;
char *new, *buffer= malloc(buffer_length);
if (buffer == 0) return 0;
while (ch= getc(f), ch != EOF) {
buffer[length]= (char)ch;
++length;
if (length == buffer_length) {
buffer_length += FGETLINE_BUFFSIZE;
if (new= realloc(buffer, buffer_length), new == 0)
{ free(buffer); return 0; }
buffer= new;
}
if (ch == '\n') break;
} /* ch == EOF || ch == '\n' */
/* check for EOF */
if (length == 0 || ferror(f)) { free(buffer); return 0; }
buffer[length]= '\0';
return buffer;
}
#endif

ian.c...@gmail.com

unread,
Jul 4, 2008, 2:34:22 PM7/4/08
to
On Jul 4, 5:59 am, Jonathan Leffler <jleff...@earthlink.net> wrote:
> ian.cot...@gmail.com wrote:
> > Sorry if this is old hat, but I haven't posted here for a decade or
> > two....
>
> > Does anyone know why the BSD (and hence Mac OS X)fgetln() function

> > didn't make it into C99? Is it being considered for a future revision
> > of the standard?
>
> At a first guess, no-one proposed it as an addition and shepherded it
> into the standard.
>
> At a second guess, after Googling 'fgetln', they did not think it well
> designed. One comment visible notes "Thefgetln() function returns a

> pointer to the next line from the specified stream. This line is not a C
> string as it does not end with a terminating null [...]".
>
> The OpenBSD manual page forfgetln() makes it clear that the returned

> pointer readily becomes invalid:
>
> Upon successful completion a pointer is returned; this pointer becomes
> invalid after the next I/O operation on stream (whether successful or
> not) or as soon as the stream is closed. Otherwise, NULL is returned.
>
> Explain to us why we would want the abomination that is gets() replaced
> byfgetln()?
>
> --
> Jonathan Leffler #include <disclaimer.h>
> Email: jleff...@earthlink.net, jleff...@us.ibm.com
> Guardian of DBD::Informix v2008.0229 --http://dbi.perl.org/

>
> publictimestamp.org/ptb/PTB-3645 tiger2 2008-07-04 03:00:06
> 784E36A3C2E87E55F53C0D1BFBB34CE06D88C9D9D83E90CB

It enables a very simple fgetline() to be written; see below.

Douglas A. Gwyn

unread,
Jul 5, 2008, 7:47:19 PM7/5/08
to
<ian.c...@gmail.com> wrote in message
news:d10baa74-1fc6-4e24...@c58g2000hsc.googlegroups.com...

> Does anyone know why the BSD (and hence Mac OS X) fgetln() function
> didn't make it into C99?

Basically, the interface isn't well designed. The C standard has so
far refused to specify library functions that malloc storage to which
a pointer is returned (e.g. strdup).

> Is it being considered for a future revision of the standard?

There is enough significant work to be done to keep WG14 busy
without spending time on random proposals.


lawrenc...@siemens.com

unread,
Jul 6, 2008, 1:14:52 PM7/6/08
to
Douglas A. Gwyn <dag...@comcast.net> wrote:
> <ian.c...@gmail.com> wrote in message
> news:d10baa74-1fc6-4e24...@c58g2000hsc.googlegroups.com...
> > Does anyone know why the BSD (and hence Mac OS X) fgetln() function
> > didn't make it into C99?
>
> Basically, the interface isn't well designed. The C standard has so
> far refused to specify library functions that malloc storage to which
> a pointer is returned (e.g. strdup).

fgetln() doesn't usually malloc storage and when it does, it's hidden in
the FILE structure. The whole point is that, in most cases, it can just
return a pointer into the file buffer and not have to copy the data at
all.

-- Larry Jones

This game lends itself to certain abuses. -- Calvin

Jun Woong

unread,
Jul 6, 2008, 10:27:30 PM7/6/08
to
lawrence.jo...@siemens.com wrote:
> Douglas A. Gwyn <dag...@comcast.net> wrote:
>
> > <ian.cot...@gmail.com> wrote in message

> >news:d10baa74-1fc6-4e24...@c58g2000hsc.googlegroups.com...
> > > Does anyone know why the BSD (and hence Mac OS X) fgetln() function
> > > didn't make it into C99?
>
> > Basically, the interface isn't well designed. The C standard has so
> > far refused to specify library functions that malloc storage to which
> > a pointer is returned (e.g. strdup).
>
> fgetln() doesn't usually malloc storage and when it does, it's hidden in
> the FILE structure. The whole point is that, in most cases, it can just
> return a pointer into the file buffer and not have to copy the data at
> all.
>

But it would always require to copy a line into the FILE structure's
malloc'ed space on an operating system where some conversion for the
newline indication is necessary, which possibly makes the point of
fgetln moot.


--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.

``All opinions expressed are mine, and do not represent
the official opinions of any organization.''

lawrenc...@siemens.com

unread,
Jul 7, 2008, 5:45:26 PM7/7/08
to
Jun Woong <wo...@icu.ac.kr> wrote:
>
> But it would always require to copy a line into the FILE structure's
> malloc'ed space on an operating system where some conversion for the
> newline indication is necessary, which possibly makes the point of
> fgetln moot.

No, newline conversion is almost always handled at a lower level by the
buffer fill and flush functions. That way, the most common operations
(getc, putc) can be very simple, usually macros that access the buffer
directly.

-- Larry Jones

When you're SERIOUS about having fun, it's not much fun at all! -- Calvin

ian.c...@gmail.com

unread,
Jul 8, 2008, 1:40:43 PM7/8/08
to

Thanks. And, just to be clear i am asking about (the BSD) fgetln() and
not the fgetline() example I wrote with it (which does have a malloc
in it). Happy to write the latter myself. In my recent version of the
old Bell Labs' diffh program, running on a Mac, the fgetline()
version written with fgetln() is _significantly_ faster than the
alternative written without it (comparing two file version of
16million lines each).
regards all,
-Ian

Jun Woong

unread,
Jul 9, 2008, 7:10:35 AM7/9/08
to
On Jul 8, 6:45 am, lawrence.jo...@siemens.com wrote:
> Jun Woong <wo...@icu.ac.kr> wrote:
>
> > But it would always require to copy a line into the FILE structure's
> > malloc'ed space on an operating system where some conversion for the
> > newline indication is necessary, which possibly makes the point of
> > fgetln moot.
>
> No, newline conversion is almost always handled at a lower level by the
> buffer fill and flush functions. That way, the most common operations
> (getc, putc) can be very simple, usually macros that access the buffer
> directly.
>

Depends on implementations. At least one implementation I studied and
mine let the FILE's buffer contain the raw bytes read from files. It
makes providing more reliable file positioning functions easier while
complicated some parts of <stdio.h> a little.


p.s. it took time to find a free news server substituting for Grubby
Google Groups.

0 new messages