Retiring gets
Walter Bright
bright at Data-IO.COM
Tue Dec 6 04:26:32 AEST 1988
In article <649 at umecs.cs.umu.se> eao at zeus.umu.se () writes:
>When I retire gets() I would like a function like this fgetline() to replace
>it. Are there any drawbacks I have missed? or is recursion to simple to use
>in problems like this? (To parse a input in search of newline.)
>/*
> * char *fgetline(file)
> * FILE *file;
> * returns a null terminated line from stdin allocated with *some_malloc
> */
> [ code deleted for brevity ]
My objections to the code presented are:
1. It depends on static variables. This makes it non-reentrant, and
therefore a bug waiting to happen on multi-threaded systems
like OS2.
2. If a 0 byte is read, the behavior is undefined.
So I present this:
size_t fgetline(FILE *file, char **pbuffer, size_t *pbufsize);
Semantics:
Reads a line from the file. The end of the line is defined by
reading a \n, or encountering the EOF. If a \n was read, it's
included in the read line. 0s may also be read, and are included
in the read line, thus the count of bytes read that's returned
may be larger than that obtained by strlen(*pbuffer).
Input:
file input stream pointer
pbuffer pointer to the buffer pointer. If the buffer pointer
is NULL, one is malloc'd. The buffer pointer must
be NULL or point to data allocated by malloc, realloc
or calloc.
pbufsize pointer to variable containing the allocated length
of the buffer
Output:
*pbuffer If the buffer needs to be realloc'd, this is set
to the new buffer.
*pbufsize Set to the size of the buffer, which may be larger
than the actual amount of data in the buffer.
Errors:
If EOF or an error occurs while a partially read line is being
read, it is treated as the end of the line.
If no bytes are read yet, 0 is returned.
If malloc or realloc run out of memory, fgetline will return what
it's already got, and errno will be set.
Returns:
number of bytes read into *pbuffer, excluding terminating 0
Example (in ANSI C):
typefile(FILE *f) /* copy file to stdout */
{ char *buffer = NULL;
size_t buflen = 0;
size_t linelen;
while (1)
{ linelen = fgetline(f,&buffer,&buflen);
if (linelen == 0) /* error or EOF */
break;
if (fwrite(buffer,1,linelen,stdout) != linelen)
break; /* error */
}
free(buffer);
}
Put a quarter in the juke,
Boogie 'till yah puke.
More information about the Comp.lang.c
mailing list