dhilst

How to read an unknown lenght line to a string in C

/*===========================*
* Reading dinamically *
*===========================*/
#include <stdio.h>
#include <stdlib.h>

#define DATALEN BUFSIZ

struct block {
char data[DATALEN];
struct block *next;
};

struct block *
alloc_block (void)
{
struct block *new = malloc (sizeof (struct block));
if (!new) {
perror ("malloc");
exit (EXIT_FAILURE);
}
return new;
}

int
readfrom (char **str, FILE *stream, int finalchar)
{
struct block *first;
struct block *ptr;
struct block *prev;
struct block *tmp;
int ch, indx = 0, nblocks = 1, strindx;

first = ptr = alloc_block();
ptr->next = NULL;
/* read and alloc string as a linked list */
while ((ch = getc(stream)) != finalchar) {
if (indx == DATALEN) {
tmp = alloc_block ();
indx = 0;
nblocks++;
tmp->next = NULL;
ptr->next = tmp;
ptr = tmp;
} else if (indx > DATALEN) {
fprintf (stderr, "readline error: Index error\n");
exit (EXIT_FAILURE);
}
ptr->data[indx++] = ch;
}
ptr->data[indx] = '\0';
*str = malloc ( (nblocks - 1) * DATALEN + indx );
/* run in list freeing it */
for
(ptr = first, strindx = 0;
ptr != NULL;
prev = ptr, ptr = ptr->next, free (prev))
{
for
(indx = 0;
indx < DATALEN && ptr->data[indx] != '\0';
indx++, strindx++)
{
(*str)[strindx] = ptr->data[indx];
}
}
(*str)[strindx] = '\0';
return strindx;
}


int
main (void)
{
char *str;
int len;
len = readfrom (&str, stdin, '\n');
printf ("Your string with len %d is `%s'\n", len, str);
return 0;
}