get a line from file pointer & pointer doesn't seem to free correctly

J

Jeff Rodriguez

There has GOT to be a standard way to this. I'm sure I'm not the only
person who would want to have a function that gets one line from a file
pointer with a dynamic length. Here's what I have right now:

( also at http://gurugeek.com/jeff/programming/wordjumble/wordjumble.c )

void get_line( FILE *fp, char **line )
{
int ch;
int iteration = 0;
char *tmp = NULL;

/* {{{ Code Fold: Loop until we reach EOF or a newline */
while ( (ch = fgetc(fp)) != '\n' && !feof(fp))
{
/* {{{ Code Fold: (Re)allocate Memory */
if ((tmp = realloc((*line), (iteration + 2) * sizeof(char))) ==
NULL )
{
puts("Memory reallocation failed\n");
exit(EXIT_FAILURE);
}
else
{
*line = tmp;
}
/* }}} Code Fold: (Re)allocate Memory */

(*line)[ iteration ] = (char)ch;
iteration++;
}
/* }}} Code Fold: Loop until we reach EOF or a newline */

}


Also, my main function:

int main( int argc, char *argv[] )
{
unsigned int count = 0;

while ( !feof(stdin) )
{
char *line = NULL;

count++;
printf("> ");
get_line(stdin, &line);
printf("%s\n", line);
// Don't forget to
free(line);
}
printf("\nTotal lines: %u\n", count);
return EXIT_SUCCESS;
}

Together they seem to give some unexpected output:

jeff@andromeda% gcc wordjumble.c
jeff@andromeda% ./a.out
long string long string
short shortstring


I'm freeing 'line' so that's the problem?
 
M

Morris Dovey

Jeff said:
There has GOT to be a standard way to this. I'm sure I'm not the only
person who would want to have a function that gets one line from a file
pointer with a dynamic length. Here's what I have right now:

Together they seem to give some unexpected output:

jeff@andromeda% gcc wordjumble.c
jeff@andromeda% ./a.out


long string


shortstring

I'm freeing 'line' so that's the problem?

Jeff...

You're forgetting to terminate the input string with '\0'.
 
R

Richard Heathfield

Jeff said:
There has GOT to be a standard way to this.

No. There are lots of ways to do this, and none of them is standard (perhaps
because nobody could decide which was the best way?).
I'm sure I'm not the only
person who would want to have a function that gets one line from a file
pointer with a dynamic length.

You're right. You're not. I now have several ways to do this, and I'm not
the only one either. See http://users.powernet.co.uk/eton/c/fgetdata.html
for a discussion of this problem (you will also find links to my own
fgetline() and fgetword() functions), or grep Google Groups for Chuck
Falconer's ggets function, which takes yet another approach to the problem.
Here's what I have right now:

( also at http://gurugeek.com/jeff/programming/wordjumble/wordjumble.c )

void get_line( FILE *fp, char **line )
{
int ch;
int iteration = 0;
char *tmp = NULL;

/* {{{ Code Fold: Loop until we reach EOF or a newline */
while ( (ch = fgetc(fp)) != '\n' && !feof(fp))
{
/* {{{ Code Fold: (Re)allocate Memory */
if ((tmp = realloc((*line), (iteration + 2) * sizeof(char))) ==
NULL )

This is going to be slow. Very slow. You realloc /every/ time you retrieve a
character.
{
puts("Memory reallocation failed\n");
exit(EXIT_FAILURE);
}
else
{
*line = tmp;
}
/* }}} Code Fold: (Re)allocate Memory */

(*line)[ iteration ] = (char)ch;
iteration++;
}
/* }}} Code Fold: Loop until we reach EOF or a newline */

Don't you think it would be a cool idea to null-terminate this "string" at
some point? :)
 
M

Morris Dovey

Jeff said:
I'm sure I'm not the only person who would want to have a
function that gets one line from a file pointer with a dynamic
length.

You're not. Nearly everyone writes at least one function to do
that job. If you're interested in recursion, you're invited to
look at a function I wrote that waits until the line is complete
before allocating an (exact sized) buffer:

http://www.iedu.com/mrd/c/getsm.c
 
J

Jeff Rodriguez

Morris said:
Jeff...

You're forgetting to terminate the input string with '\0'.
Ahh, my origional code had that in there, then I posted another question
on here and someone removed that piece of my code. I assumed that malloc
/ realloc would \0 it all out but I guess not.

Thanks
Jeff
 
C

CBFalconer

Jeff said:
There has GOT to be a standard way to this. I'm sure I'm not the
only person who would want to have a function that gets one line
from a file pointer with a dynamic length. ... snip ...

There are several. Richard Heathfield has one, and so do I. Mine
is designed for simplicity of use, and available at:

<http://cbfalconer.home.att.net/download/ggets.zip>

Get 'em, examine 'em, choose.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top