reading line by line from file

C

CBFalconer

William said:
The prototype of ggets is "int ggets(char **ln);"
and for fggets is "int fggets(char **ln, FILE *f);"

My theory is that, having gotten complete lines, we are not in the
least interested in the terminating \n. The routine is written in
standard C, so is available anywhere. Returning the linelength
would be possible, but would complicate the simplified interface,
and thus could lead to errors. The return differentiates between
file errors/EOF and memory exhaustion.

The user has no control of trailing space stripping, that is
entirely up to the file system, not the interface routines. If the
blanks are there, ggets will return them.

What are the prototypes for fgetln and fparseln?

char *fgetln(FILE *stream, size_t *len);

char *fparseln(FILE *stream, size_t *len, size_t *lineno,
const char delim[3], int flags);
.... snip ...

GNU getline(), I think, is a great compromise between fgetln() and
ggets(): ssize_t getline(char **buf, size_t *bufsiz, FILE *).
It's one of the rare GNU extensions that does most everything you
want in a more-or-less elegant manner:

getline() reads an entire line, storing the address of the buffer
containing the text into *lineptr. The buffer is null-terminated
and includes the newline character, if a newline delimiter was found.

If *lineptr is NULL, the getline() routine will allocate a buffer
for containing the line, which must be freed by the user program.
Alternatively, before calling getline(), *lineptr can contain a
pointer to a malloc()-allocated buffer *n bytes in size. If the buffer
is not large enough to hold the line read in, getline() resizes the
buffer to fit with realloc(), updating *lineptr and *n as necessary.
In either case, on a successful call, *lineptr and *n will be
updated to reflect the buffer address and size respectively.

...

On success, getline() ... return the number of characters
read, including the delimiter character, but not including the
terminating null character.


My problem with that, and what I tried to avoid with ggets, is that
there are things to remember in calling it. I can remember one
thing fairly reliably. That is why ggets takes entire care of the
memory allocation, and doesn't need anything initialized. The user
just has to remember that the returned storage needs eventual
freeing. If anything needs copying it will be just the returned
pointer. Thus typical usage is:

char *ln;

while (0 == ggets(&ln) {
/* do unspeakable things with ln */
}
/* If a collection of lns have been saved */
while (something) {
ln = something.ln;
something = something.next;
free(ln);
}

'something' can be an array of char*, and the result easily
implements tail.

Lets face it, people use gets because the interface is so simple.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top